idlehomescreen/xmluirendering/renderingplugins/xnnewstickerfactory/src/xnnewstickercontrol.cpp
changeset 0 f72a12da539e
child 1 5315654608de
equal deleted inserted replaced
-1:000000000000 0:f72a12da539e
       
     1 /*
       
     2 * Copyright (c) 2002-2006 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Text scrolling functionality.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include <AknUtils.h>
       
    21 #include <gulicon.h>
       
    22 #include <AknsDrawUtils.h>
       
    23 #include <AknBidiTextUtils.h>
       
    24 
       
    25 #include "xnnewstickercontrol.h"
       
    26 #include "xnnewstickeradapter.h"
       
    27 #include "xnproperty.h"
       
    28 
       
    29 // CONSTANTS
       
    30 /**
       
    31 * for the empty space in pixels between text and image.
       
    32 */
       
    33 const TInt KGap = 10;
       
    34 
       
    35    
       
    36 // ============================ MEMBER FUNCTIONS ===============================
       
    37 
       
    38 // -----------------------------------------------------------------------------
       
    39 // CXnNewstickerControl::CTitleData::CTitleData
       
    40 // C++ default constructor can NOT contain any code, that
       
    41 // might leave.
       
    42 // -----------------------------------------------------------------------------
       
    43 //
       
    44 CXnNewstickerControl::CTitleData::CTitleData(TInt aLenghtInPixels) :
       
    45     iTitleIsSvg(EFalse), iTextLenghtInPixels(aLenghtInPixels)
       
    46     {
       
    47     }
       
    48 
       
    49 // -----------------------------------------------------------------------------
       
    50 // Destructor
       
    51 // -----------------------------------------------------------------------------
       
    52 //
       
    53 CXnNewstickerControl::CTitleData::~CTitleData()
       
    54     {
       
    55     delete iText;
       
    56     delete iData;
       
    57     }
       
    58 
       
    59 // -----------------------------------------------------------------------------
       
    60 // CXnNewstickerControl::CTitleData::ConstructL
       
    61 // Symbian 2nd phase constructor can leave.
       
    62 // -----------------------------------------------------------------------------
       
    63 //
       
    64 void CXnNewstickerControl::CTitleData::ConstructL(const TDesC& aTitle)
       
    65     {
       
    66     delete iText;
       
    67     iText = NULL;
       
    68     iText = aTitle.AllocL();
       
    69     }
       
    70 
       
    71 // -----------------------------------------------------------------------------
       
    72 // CXnNewstickerControl::CTitleData::ConstructL
       
    73 // Symbian 2nd phase constructor can leave.
       
    74 // -----------------------------------------------------------------------------
       
    75 //
       
    76 void CXnNewstickerControl::CTitleData::ConstructL(const TDesC8& aByteData)
       
    77     {
       
    78     iTitleIsSvg = ETrue;
       
    79     iData = aByteData.AllocL();
       
    80     iText = KNullDesC().AllocL();
       
    81     }
       
    82 
       
    83 // -----------------------------------------------------------------------------
       
    84 // CXnNewstickerControl::CTitleData::NewL
       
    85 // Two-phased constructor.
       
    86 // -----------------------------------------------------------------------------
       
    87 //
       
    88 CXnNewstickerControl::CTitleData* CXnNewstickerControl::CTitleData::NewL(
       
    89                 const TDesC& aTitle, TInt aLenghtInPixels)
       
    90     {
       
    91     CXnNewstickerControl::CTitleData* self =
       
    92             CXnNewstickerControl::CTitleData::NewLC(aTitle, aLenghtInPixels);
       
    93     CleanupStack::Pop(self);
       
    94     return self;
       
    95     }
       
    96 
       
    97 // -----------------------------------------------------------------------------
       
    98 // CXnNewstickerControl::CTitleData::NewLC
       
    99 // Two-phased constructor.
       
   100 // -----------------------------------------------------------------------------
       
   101 //
       
   102 CXnNewstickerControl::CTitleData* CXnNewstickerControl::CTitleData::NewLC(
       
   103                 const TDesC& aTitle, TInt aLenghtInPixels)
       
   104     {
       
   105     CXnNewstickerControl::CTitleData* self =
       
   106             new(ELeave) CXnNewstickerControl::CTitleData(aLenghtInPixels);
       
   107     CleanupStack::PushL(self);
       
   108     self->ConstructL(aTitle);
       
   109     return self;
       
   110     }
       
   111 
       
   112 // -----------------------------------------------------------------------------
       
   113 // CXnNewstickerControl::CTitleData::NewL
       
   114 // Two-phased constructor.
       
   115 // -----------------------------------------------------------------------------
       
   116 //
       
   117 CXnNewstickerControl::CTitleData* CXnNewstickerControl::CTitleData::NewL(
       
   118                 const TDesC8& aByteData)
       
   119     {
       
   120     CXnNewstickerControl::CTitleData* self =
       
   121             CXnNewstickerControl::CTitleData::NewLC(aByteData);
       
   122     CleanupStack::Pop(self);
       
   123     return self;
       
   124     }
       
   125 
       
   126 // -----------------------------------------------------------------------------
       
   127 // CXnNewstickerControl::CTitleData::NewLC
       
   128 // Two-phased constructor.
       
   129 // -----------------------------------------------------------------------------
       
   130 //
       
   131 CXnNewstickerControl::CTitleData* CXnNewstickerControl::CTitleData::NewLC(
       
   132                 const TDesC8& aByteData)
       
   133     {
       
   134     CXnNewstickerControl::CTitleData* self =
       
   135             new(ELeave) CXnNewstickerControl::CTitleData();
       
   136     CleanupStack::PushL(self);
       
   137     self->ConstructL(aByteData);
       
   138     return self;
       
   139     }
       
   140 
       
   141 // -----------------------------------------------------------------------------
       
   142 // CXnNewstickerControl::CTitleData::TitleText
       
   143 // (other items were commented in a header).
       
   144 // -----------------------------------------------------------------------------
       
   145 //
       
   146 const TDesC& CXnNewstickerControl::CTitleData::TitleText()
       
   147     {
       
   148     return *iText;
       
   149     }
       
   150 
       
   151 // -----------------------------------------------------------------------------
       
   152 // CXnNewstickerControl::CTitleData::SetTitleText
       
   153 // (other items were commented in a header).
       
   154 // -----------------------------------------------------------------------------
       
   155 //
       
   156 void CXnNewstickerControl::CTitleData::SetTitleTextL(const TDesC& aTitle)
       
   157     {
       
   158     HBufC* newTitle = aTitle.AllocL();
       
   159     delete iText;
       
   160     iText = newTitle;
       
   161     }
       
   162 
       
   163 // -----------------------------------------------------------------------------
       
   164 // CXnNewstickerControl::CTitleData::TitleTextLengthInPixels
       
   165 // (other items were commented in a header).
       
   166 // -----------------------------------------------------------------------------
       
   167 //
       
   168 TInt CXnNewstickerControl::CTitleData::TitleTextLengthInPixels()
       
   169     {
       
   170     return iTextLenghtInPixels;
       
   171     }
       
   172 
       
   173 // -----------------------------------------------------------------------------
       
   174 // CXnNewstickerControl::CTitleData::SetTitleTextLengthInPixels
       
   175 // (other items were commented in a header).
       
   176 // -----------------------------------------------------------------------------
       
   177 //
       
   178 void CXnNewstickerControl::CTitleData::SetTitleTextLengthInPixels(TInt aLenghtInPixels)
       
   179     {
       
   180     iTextLenghtInPixels = aLenghtInPixels;    
       
   181     }
       
   182 
       
   183 // -----------------------------------------------------------------------------
       
   184 // CXnNewstickerControl::CTitleData::IsSvgTitle
       
   185 // (other items were commented in a header).
       
   186 // -----------------------------------------------------------------------------
       
   187 //
       
   188 TBool CXnNewstickerControl::CTitleData::IsSvgTitle()
       
   189     {
       
   190     return iTitleIsSvg;
       
   191     }
       
   192 
       
   193 // -----------------------------------------------------------------------------
       
   194 // CXnNewstickerControl::CTitleData::SvgTitleData
       
   195 // (other items were commented in a header).
       
   196 // -----------------------------------------------------------------------------
       
   197 //
       
   198 const TDesC8& CXnNewstickerControl::CTitleData::SvgTitleData()
       
   199     {
       
   200     return *iData;
       
   201     }
       
   202 
       
   203 // -----------------------------------------------------------------------------
       
   204 // CXnNewstickerControl::CXnNewstickerControl
       
   205 // C++ default constructor can NOT contain any code, that
       
   206 // might leave.
       
   207 // -----------------------------------------------------------------------------
       
   208 //
       
   209 CXnNewstickerControl::CXnNewstickerControl(CXnNewstickerAdapter* aAdapter) :     
       
   210     iFirstDrawingTitleIndex(0),
       
   211     iFirstDrawingOffset(0),
       
   212     iImageWidthInPixels(0),
       
   213     iCurrentTitleIndex(-1),
       
   214     iSeparatorimage(NULL),
       
   215     iSeparatorImageWidth(0),
       
   216     iFont(NULL),
       
   217     iTextBaseline(0),
       
   218     iTextColor(KRgbBlack),
       
   219     iUnderlining(EUnderlineOff),
       
   220     iStrikethrough(EStrikethroughOff),
       
   221     iIsWestern(ETrue),
       
   222     iAdapter(aAdapter),
       
   223     iTextAlignment(ELayoutAlignLeft)
       
   224     {
       
   225     }
       
   226 
       
   227 // -----------------------------------------------------------------------------
       
   228 // CXnNewstickerControl::ConstructL
       
   229 // Symbian 2nd phase constructor can leave.
       
   230 // -----------------------------------------------------------------------------
       
   231 //
       
   232 void CXnNewstickerControl::ConstructL()
       
   233     {
       
   234     if(AknLayoutUtils::LayoutMirrored())
       
   235         {
       
   236     	iIsWestern = EFalse;
       
   237         iTextAlignment = ELayoutAlignRight;
       
   238         }
       
   239     }
       
   240 
       
   241 // -----------------------------------------------------------------------------
       
   242 // CXnNewstickerControl::NewL
       
   243 // Two-phased constructor.
       
   244 // -----------------------------------------------------------------------------
       
   245 //
       
   246 CXnNewstickerControl* CXnNewstickerControl::NewL(CXnNewstickerAdapter* aAdapter)
       
   247     {
       
   248     CXnNewstickerControl* self = new(ELeave)CXnNewstickerControl(aAdapter);
       
   249     CleanupStack::PushL(self);
       
   250     self->ConstructL();
       
   251     CleanupStack::Pop();    
       
   252     return self;
       
   253     }
       
   254 
       
   255 // -----------------------------------------------------------------------------
       
   256 // CXnNewstickerControl::~CXnNewstickerControl()
       
   257 // Destructor.
       
   258 // -----------------------------------------------------------------------------
       
   259 //
       
   260 CXnNewstickerControl::~CXnNewstickerControl()
       
   261     {
       
   262     iTitles.ResetAndDestroy();
       
   263     delete iSeparatorimage;
       
   264     }
       
   265 
       
   266 // -----------------------------------------------------------------------------
       
   267 // CXnNewstickerControl::SetScrollAmount
       
   268 // (other items were commented in a header).
       
   269 // -----------------------------------------------------------------------------
       
   270 //
       
   271 void CXnNewstickerControl::SetScrollAmount(TInt aScrollAmount)
       
   272     {
       
   273     iSpeed = aScrollAmount;
       
   274     }
       
   275 
       
   276 // -----------------------------------------------------------------------------
       
   277 // CXnNewstickerControl::SetNewstickerRect
       
   278 // Set visible rect.
       
   279 // (other items were commented in a header).
       
   280 // -----------------------------------------------------------------------------
       
   281 //
       
   282 void CXnNewstickerControl::SetNewstickerRect(TRect& aContentRect)
       
   283     {
       
   284     if(iContentRect != aContentRect)
       
   285         {
       
   286         iContentRect = aContentRect;
       
   287         iTextBaseline = iContentRect.Height() / 2 + iFont->AscentInPixels() / 2;
       
   288         SetBeginningState();
       
   289         for(TInt i = 0; i < iTitles.Count(); i++)
       
   290             {
       
   291             if(!iTitles[i]->IsSvgTitle())
       
   292                 {
       
   293                 TInt textWidth = iFont->TextWidthInPixels(
       
   294                     iTitles[i]->TitleText());
       
   295                 iTitles[i]->SetTitleTextLengthInPixels(textWidth);
       
   296                 }
       
   297             }
       
   298         CalculateTextFitInNewstickerRect();        
       
   299         }
       
   300     }
       
   301 
       
   302 // -----------------------------------------------------------------------------
       
   303 // CXnNewstickerControl::IsWestern
       
   304 // Returns ETrue if western layout is used, otherwise EFalse is returned.
       
   305 // (other items were commented in a header).
       
   306 // -----------------------------------------------------------------------------
       
   307 //
       
   308 TBool CXnNewstickerControl::IsWestern()
       
   309     {
       
   310     return iIsWestern;
       
   311     }
       
   312 
       
   313 // -----------------------------------------------------------------------------
       
   314 // CXnNewstickerControl::AppendTitleL
       
   315 // (other items were commented in a header).
       
   316 // -----------------------------------------------------------------------------
       
   317 //
       
   318 void CXnNewstickerControl::AppendTitleL(const TDesC& aTitle)
       
   319     {
       
   320     TInt textWidth = iFont->TextWidthInPixels(aTitle);
       
   321     CTitleData* title = CTitleData::NewLC(aTitle, textWidth);
       
   322     iTitles.AppendL(title);
       
   323     CleanupStack::Pop(title);
       
   324     
       
   325     CalculateTextFitInNewstickerRect();    
       
   326 
       
   327     // if this is the first item
       
   328     if(iTitles.Count() == 1) 
       
   329         {
       
   330         iCurrentTitleIndex = 0;
       
   331         iAdapter->StartL();    
       
   332         }
       
   333     }
       
   334 
       
   335 // ---------------------------------------------------------
       
   336 // CXnNewstickerControl::InsertTitleL
       
   337 // ---------------------------------------------------------
       
   338 //
       
   339 void CXnNewstickerControl::InsertTitleL(const TDesC& aTitle, TInt aIndex)
       
   340     {
       
   341     TInt textWidth = iFont->TextWidthInPixels(aTitle);
       
   342     CTitleData* title = CTitleData::NewLC(aTitle, textWidth);
       
   343     iTitles.InsertL(title, aIndex);
       
   344     CleanupStack::Pop(title);
       
   345 
       
   346     
       
   347     CountIndexAfterInsertL(aIndex);
       
   348     CalculateTextFitInNewstickerRect();    
       
   349     }
       
   350 
       
   351 // ---------------------------------------------------------
       
   352 // CXnNewstickerControl::UpdateTitleL
       
   353 // ---------------------------------------------------------
       
   354 //
       
   355 void CXnNewstickerControl::UpdateTitleL(const TDesC& aTitle, TInt aIndex)
       
   356     {
       
   357     if ( aIndex >= 0 && aIndex < iTitles.Count() )
       
   358         {
       
   359         CTitleData* titleData = iTitles[aIndex];    
       
   360         TInt textWidth = iFont->TextWidthInPixels(aTitle);
       
   361         titleData->SetTitleTextL(aTitle);
       
   362         titleData->SetTitleTextLengthInPixels(textWidth);
       
   363         CalculateTextFitInNewstickerRect();
       
   364         }
       
   365     else
       
   366         {
       
   367         AppendTitleL(aTitle);
       
   368         }
       
   369     }
       
   370 
       
   371 // ---------------------------------------------------------
       
   372 // CXnNewstickerControl::DeleteTitle
       
   373 // ---------------------------------------------------------
       
   374 //
       
   375 void CXnNewstickerControl::DeleteTitleL(TInt aIndex)
       
   376     {
       
   377     TInt count = iTitles.Count();
       
   378     if (aIndex >= 0 && aIndex < count)
       
   379         {
       
   380         // If the last item will be deleted
       
   381         if(count == 1)
       
   382             {
       
   383             iAdapter->StopL();
       
   384             iFirstDrawingTitleIndex = GetNextTitleWithContent( 0 );
       
   385             SetBeginningState();
       
   386             iCurrentTitleIndex = -1;
       
   387             }
       
   388         if (aIndex == iFirstDrawingTitleIndex)
       
   389             {
       
   390             // If this happens to be the last item in the list
       
   391             if(aIndex == count - 1)
       
   392                 {
       
   393                 iFirstDrawingTitleIndex = GetNextTitleWithContent( 0 );
       
   394                 }
       
   395             SetBeginningState();
       
   396             iCurrentTitleIndex = iFirstDrawingTitleIndex;
       
   397             }
       
   398             
       
   399         //  Check if the title was deleted before the current title
       
   400         else if (aIndex < iFirstDrawingTitleIndex)
       
   401             {
       
   402             iCurrentTitleIndex--;
       
   403             iFirstDrawingTitleIndex = GetNextTitleWithContent( iFirstDrawingTitleIndex-1, ETrue);
       
   404             }
       
   405         UpdateTitleL(KNullDesC, aIndex);
       
   406         CalculateTextFitInNewstickerRect();        
       
   407         }
       
   408     }
       
   409 
       
   410 // ---------------------------------------------------------
       
   411 // CXnNewstickerControl::CurrentTitleIndex
       
   412 // ---------------------------------------------------------
       
   413 //
       
   414 TInt CXnNewstickerControl::CurrentTitleIndex()
       
   415     {
       
   416     return iCurrentTitleIndex;
       
   417     }
       
   418 
       
   419 // ---------------------------------------------------------
       
   420 // CXnNewstickerControl::Title
       
   421 // ---------------------------------------------------------
       
   422 //
       
   423 const TDesC& CXnNewstickerControl::Title(TInt aIndex)
       
   424     {
       
   425     if (aIndex < 0 || aIndex > iTitles.Count())
       
   426         {
       
   427         return KNullDesC;
       
   428         }
       
   429 
       
   430     if (iTitles[aIndex]->IsSvgTitle())
       
   431         {
       
   432         return KNullDesC;
       
   433         }
       
   434 
       
   435     return iTitles[aIndex]->TitleText();
       
   436     }
       
   437 
       
   438 // ---------------------------------------------------------
       
   439 // CXnNewstickerControl::SetSeparatorImageL
       
   440 // ---------------------------------------------------------
       
   441 //
       
   442 TInt CXnNewstickerControl::SetSeparatorImageL(CGulIcon* aIcon)
       
   443     {
       
   444     CFbsBitmap* bitmap = aIcon->Bitmap();
       
   445     if(AknIconUtils::IsMifIcon(bitmap))
       
   446         {
       
   447         delete iSeparatorimage;
       
   448         iSeparatorimage = aIcon;
       
   449         TInt maxHeight = iContentRect.Height();
       
   450         TSize size = TSize(maxHeight, maxHeight);        
       
   451         AknIconUtils::SetSize(bitmap, size, EAspectRatioPreservedAndUnusedSpaceRemoved);
       
   452         iSeparatorImageWidth = bitmap->SizeInPixels().iWidth + KGap;
       
   453         return KErrNone;
       
   454         }
       
   455     else
       
   456         {
       
   457         iSeparatorimage = NULL;
       
   458         return KErrNotSupported;
       
   459         }
       
   460     }
       
   461 
       
   462 // ---------------------------------------------------------
       
   463 // CXnNewstickerControl::ClearTitles
       
   464 // ---------------------------------------------------------
       
   465 //
       
   466 void CXnNewstickerControl::ClearTitles()
       
   467     {
       
   468     TRAP_IGNORE(iAdapter->StopL());
       
   469     iFirstDrawingTitleIndex = 0;
       
   470     SetBeginningState();
       
   471     iCurrentTitleIndex = -1;
       
   472     // Don't delete just clear the contents
       
   473     for( TInt i = 0; i < iTitles.Count(); ++i )
       
   474         {
       
   475         TRAP_IGNORE( UpdateTitleL( KNullDesC, i ) );
       
   476         }
       
   477     iTextFitInNewstickerRect = EFalse;
       
   478     }
       
   479 
       
   480 // ---------------------------------------------------------
       
   481 // CXnNewstickerControl::AppendSvgTitleL
       
   482 // ---------------------------------------------------------
       
   483 //
       
   484 void CXnNewstickerControl::AppendSvgTitleL(const TDesC8& aByteData)
       
   485     {
       
   486     CTitleData* title = CTitleData::NewLC(aByteData);
       
   487     iTitles.AppendL(title);
       
   488     CleanupStack::Pop(title);
       
   489     
       
   490     // if this is the first item
       
   491     if(iTitles.Count() == 1) 
       
   492         {
       
   493         iCurrentTitleIndex = 0;
       
   494         iAdapter->StartL();
       
   495         }
       
   496     }
       
   497 
       
   498 // ---------------------------------------------------------
       
   499 // CXnNewstickerControl::InsertSvgTitleL
       
   500 // ---------------------------------------------------------
       
   501 //
       
   502 void CXnNewstickerControl::InsertSvgTitleL(const TDesC8& aByteData, TInt aIndex)
       
   503     {
       
   504     CTitleData* title = CTitleData::NewLC(aByteData);
       
   505     iTitles.InsertL(title, aIndex);
       
   506     CleanupStack::Pop(title);
       
   507     CountIndexAfterInsertL(aIndex);
       
   508     }
       
   509 
       
   510 // ---------------------------------------------------------
       
   511 // CXnNewstickerControl::CurrentSvgTitle
       
   512 // ---------------------------------------------------------
       
   513 //
       
   514 const TDesC8& CXnNewstickerControl::CurrentSvgTitle()
       
   515     {
       
   516     CTitleData* title = iTitles[iFirstDrawingTitleIndex];
       
   517     //  Is it SVG title
       
   518     if (title->IsSvgTitle())
       
   519         {
       
   520         //  Yes, advance the title index
       
   521         iFirstDrawingTitleIndex++;
       
   522         if (iFirstDrawingTitleIndex >= iTitles.Count())
       
   523             {
       
   524             iFirstDrawingTitleIndex = 0;
       
   525             }
       
   526 
       
   527         //  Return the data
       
   528         return title->SvgTitleData();
       
   529         }
       
   530 
       
   531     //  Not svg title, return empty desc
       
   532     return KNullDesC8;
       
   533     }
       
   534 
       
   535 // ---------------------------------------------------------
       
   536 // CXnNewstickerControl::TitleCount
       
   537 // ---------------------------------------------------------
       
   538 //
       
   539 TInt CXnNewstickerControl::TitleCount() const
       
   540     {
       
   541     return iTitles.Count();
       
   542     }
       
   543 
       
   544 // -----------------------------------------------------------------------------
       
   545 // CXnNewstickerControl::MoveToNext
       
   546 // -----------------------------------------------------------------------------
       
   547 //
       
   548 void CXnNewstickerControl::MoveToNextL()
       
   549     {
       
   550     //  If there are no titles, don't do anything.
       
   551     if (!IsVisibleTitles())
       
   552         {
       
   553         return ;
       
   554         }
       
   555     // Skip notification of the first title
       
   556     if ( iCurrentTitleIndex != GetNextTitleWithContent( 0 ) )
       
   557         {
       
   558         iAdapter->ReportNewstickerEventL(XnPropertyNames::action::trigger::name::KTitleScrolled);
       
   559         }
       
   560     // Don't report the last TitleToScroll in case the scroll ended
       
   561     if ( iAdapter->CurrentState() != CXnNewstickerAdapter::EScrollEnded )
       
   562         {    
       
   563         iAdapter->ReportNewstickerEventL(XnPropertyNames::action::trigger::name::KTitleToScroll);
       
   564         }
       
   565     iAdapter->TitleScrolled(iFirstDrawingTitleIndex);
       
   566     if (iAdapter->CurrentState() == CXnNewstickerAdapter::EAnimation)
       
   567         {
       
   568         iCurrentTitleIndex = GetNextTitleWithContent( iCurrentTitleIndex + 1 );
       
   569         iFirstDrawingTitleIndex = iCurrentTitleIndex;
       
   570         }
       
   571     else
       
   572         {
       
   573         iCurrentTitleIndex = GetNextTitleWithContent( iFirstDrawingTitleIndex + 1);
       
   574         iFirstDrawingTitleIndex = iCurrentTitleIndex;
       
   575         }
       
   576 
       
   577     //  Check that we are still in range
       
   578     if (iFirstDrawingTitleIndex >= iTitles.Count() || iFirstDrawingTitleIndex < 0)
       
   579         {
       
   580         iFirstDrawingTitleIndex = GetNextTitleWithContent( 0 );
       
   581         iCurrentTitleIndex = iFirstDrawingTitleIndex;
       
   582         }
       
   583 
       
   584     SetBeginningState();
       
   585     }
       
   586 
       
   587 // -----------------------------------------------------------------------------
       
   588 // CXnNewstickerControl::MoveToFirstL
       
   589 // -----------------------------------------------------------------------------
       
   590 //
       
   591 void CXnNewstickerControl::MoveToFirstL()
       
   592     {
       
   593     //  If there are no titles, don't do anything.
       
   594     if (!IsVisibleTitles())
       
   595         {
       
   596         return ;
       
   597         }
       
   598     // Something already scrolling, report scroll done
       
   599     if ( iAdapter->CurrentState() == CXnNewstickerAdapter::EText )
       
   600         {
       
   601         iAdapter->ReportNewstickerEventL(XnPropertyNames::action::trigger::name::KTitleScrolled);
       
   602         iAdapter->TitleScrolled(iFirstDrawingTitleIndex);
       
   603         }
       
   604        
       
   605     TInt start = 0; // iIsWestern ? 0 : (iTitles.Count() - 1);
       
   606     
       
   607     iCurrentTitleIndex = GetNextTitleWithContent( start );
       
   608     iFirstDrawingTitleIndex = iCurrentTitleIndex;
       
   609     iAdapter->ReportNewstickerEventL(XnPropertyNames::action::trigger::name::KTitleToScroll);
       
   610     SetBeginningState();
       
   611     }
       
   612 
       
   613 // -----------------------------------------------------------------------------
       
   614 // CXnNewstickerControl::MoveToLastL
       
   615 // -----------------------------------------------------------------------------
       
   616 //
       
   617 void CXnNewstickerControl::MoveToLastL()
       
   618     {
       
   619     //  If there are no titles, don't do anything.
       
   620     if (!IsVisibleTitles())
       
   621         {
       
   622         return ;
       
   623         }
       
   624     // Something already scrolling, report scroll done
       
   625     if ( iAdapter->CurrentState() == CXnNewstickerAdapter::EText )
       
   626         {
       
   627         iAdapter->ReportNewstickerEventL(XnPropertyNames::action::trigger::name::KTitleScrolled);
       
   628         iAdapter->TitleScrolled(iFirstDrawingTitleIndex);
       
   629         }
       
   630     
       
   631     TInt start = iTitles.Count() - 1; // iIsWestern ? (iTitles.Count() - 1) : 0;
       
   632     
       
   633     iCurrentTitleIndex = GetNextTitleWithContent( start, ETrue );
       
   634     iFirstDrawingTitleIndex = iCurrentTitleIndex;
       
   635     iAdapter->ReportNewstickerEventL(XnPropertyNames::action::trigger::name::KTitleToScroll);
       
   636     SetBeginningState();
       
   637     }
       
   638 // -----------------------------------------------------------------------------
       
   639 // CXnNewstickerControl::MoveToPrev
       
   640 // -----------------------------------------------------------------------------
       
   641 //
       
   642 void CXnNewstickerControl::MoveToPrevL()
       
   643     {
       
   644     //  If there are no titles, don't do anything.
       
   645     if (!IsVisibleTitles())
       
   646         {
       
   647         return ;
       
   648         }
       
   649     
       
   650     iAdapter->ReportNewstickerEventL(XnPropertyNames::action::trigger::name::KTitleScrolled);
       
   651 
       
   652     if (iAdapter->CurrentState() == CXnNewstickerAdapter::EAnimation)
       
   653         {
       
   654         iCurrentTitleIndex = GetNextTitleWithContent( iCurrentTitleIndex - 1, ETrue );        
       
   655         iFirstDrawingTitleIndex = iCurrentTitleIndex;
       
   656         }
       
   657     else
       
   658         {
       
   659         iFirstDrawingTitleIndex = GetNextTitleWithContent( iFirstDrawingTitleIndex - 1, ETrue );
       
   660         iCurrentTitleIndex = iFirstDrawingTitleIndex;
       
   661         }
       
   662     //  Check that we are still in range
       
   663     if (iFirstDrawingTitleIndex >= iTitles.Count() || iFirstDrawingTitleIndex < 0)
       
   664         {
       
   665         iFirstDrawingTitleIndex = GetNextTitleWithContent( iTitles.Count() - 1, ETrue );
       
   666         iCurrentTitleIndex = iFirstDrawingTitleIndex;
       
   667         }
       
   668     
       
   669     iAdapter->ReportNewstickerEventL(XnPropertyNames::action::trigger::name::KTitleToScroll);
       
   670     SetBeginningState();
       
   671     }
       
   672 
       
   673 // -----------------------------------------------------------------------------
       
   674 // CXnNewstickerControl::MoveToCurrent
       
   675 // -----------------------------------------------------------------------------
       
   676 //
       
   677 void CXnNewstickerControl::MoveToCurrent()
       
   678     {
       
   679     //  If there are no titles, don't do anything.
       
   680     if (!IsVisibleTitles())
       
   681         {
       
   682         return ;
       
   683         }
       
   684 
       
   685     iFirstDrawingTitleIndex = iCurrentTitleIndex;
       
   686     SetBeginningState();    
       
   687     }
       
   688 
       
   689 // -----------------------------------------------------------------------------
       
   690 // CXnNewstickerControl::CountIndexAfterInsert
       
   691 // -----------------------------------------------------------------------------
       
   692 //
       
   693 void CXnNewstickerControl::CountIndexAfterInsertL(TInt aIndex)
       
   694     {
       
   695     //  Check if the new title was inserted before the first drawing title
       
   696     if (aIndex <= iFirstDrawingTitleIndex)
       
   697         {
       
   698         iCurrentTitleIndex++;
       
   699         iFirstDrawingTitleIndex++;
       
   700         }
       
   701         
       
   702     // if this is the first item
       
   703     if(iTitles.Count() == 1 && GetNextTitleWithContent( 0 ) == 0) 
       
   704         {
       
   705         iCurrentTitleIndex = 0;
       
   706         iFirstDrawingTitleIndex = 0;
       
   707         iAdapter->StartL();
       
   708         }
       
   709     }
       
   710 
       
   711 // -----------------------------------------------------------------------------
       
   712 // CXnNewstickerControl::SetFont
       
   713 // -----------------------------------------------------------------------------
       
   714 void CXnNewstickerControl::SetFont(CFont* aFont)
       
   715     {
       
   716     if(iFont != aFont)
       
   717         {
       
   718         for(TInt i = 0; i < iTitles.Count(); i++)
       
   719             {
       
   720             if(!iTitles[i]->IsSvgTitle())
       
   721                 {
       
   722                 TInt textWidth = aFont->TextWidthInPixels(
       
   723                     iTitles[i]->TitleText());
       
   724                 iTitles[i]->SetTitleTextLengthInPixels(textWidth);
       
   725                 }
       
   726             }
       
   727         iFont = aFont;
       
   728         iTextBaseline = iContentRect.Height() / 2 + iFont->AscentInPixels() / 2;
       
   729         CBitmapContext* gc = iAdapter->BufferGc();
       
   730         if(gc)
       
   731             {
       
   732             gc->UseFont(aFont);
       
   733             }
       
   734         }
       
   735     }
       
   736 
       
   737 // -----------------------------------------------------------------------------
       
   738 // CXnNewstickerControl::SetTextColor
       
   739 // -----------------------------------------------------------------------------
       
   740 void CXnNewstickerControl::SetTextColor(TRgb aColor)
       
   741     {
       
   742     iTextColor = aColor;
       
   743     CBitmapContext* gc = iAdapter->BufferGc();
       
   744     if(gc)
       
   745         {
       
   746         gc->SetPenColor(iTextColor);
       
   747         }
       
   748     }
       
   749 
       
   750 // -----------------------------------------------------------------------------
       
   751 // CXnNewstickerControl::SetTextUnderlineStyle
       
   752 // -----------------------------------------------------------------------------
       
   753 void CXnNewstickerControl::SetTextUnderlineStyle(TFontUnderline aStyle)
       
   754     {
       
   755     iUnderlining = aStyle;
       
   756     CBitmapContext* gc = iAdapter->BufferGc();
       
   757     if(gc)
       
   758         {
       
   759         gc->SetUnderlineStyle(iUnderlining);        
       
   760         }
       
   761     }
       
   762 
       
   763 // -----------------------------------------------------------------------------
       
   764 // CXnNewstickerControl::SetTextUnderlineStyle
       
   765 // -----------------------------------------------------------------------------
       
   766 void CXnNewstickerControl::SetTextStrikethroughStyle(TFontStrikethrough aStyle)
       
   767     {
       
   768     iStrikethrough = aStyle;
       
   769     CBitmapContext* gc = iAdapter->BufferGc();
       
   770     if(gc)
       
   771         {
       
   772         gc->SetStrikethroughStyle(iStrikethrough);        
       
   773         }
       
   774     }
       
   775 
       
   776 // -----------------------------------------------------------------------------
       
   777 // CXnNewstickerControl::PrepareToDrawL
       
   778 // (other items were commented in a header).
       
   779 // -----------------------------------------------------------------------------
       
   780 //
       
   781 void CXnNewstickerControl::PrepareToDrawLtrL()
       
   782     {
       
   783     CBitmapContext* gc = iAdapter->BufferGc();
       
   784     const CFbsBitmap* background = iAdapter->BackgroundBitmap();
       
   785     if(!gc || !background || !IsVisibleTitles() )
       
   786         {
       
   787         return;
       
   788         }
       
   789     iFirstDrawingTitleIndex = GetNextTitleWithContent( iFirstDrawingTitleIndex );
       
   790     if ( iFirstDrawingTitleIndex < 0 )
       
   791         {
       
   792         return;
       
   793         }
       
   794     if (iTitles[iFirstDrawingTitleIndex]->IsSvgTitle())
       
   795         {
       
   796         //  Show SVG title
       
   797         iAdapter->ShowSvgL();
       
   798         
       
   799     	// Just in case, draw background to d-buffer
       
   800         gc->BitBlt(TPoint(0,0), background);
       
   801         return;
       
   802         }
       
   803 
       
   804     CGraphicsContext::TTextAlign alignment = TextAlignment();
       
   805     if ( iTextFitInNewstickerRect || 
       
   806          iAdapter->ScrollBehaviour() == CXnNewstickerAdapter::EAlternate && iTitles.Count() == 1 )
       
   807         {
       
   808         iAdapter->StopL();
       
   809         SetBeginningState();
       
   810         }
       
   811     
       
   812 	TInt drawingPos(-iFirstDrawingOffset);
       
   813 
       
   814 	// At first, draw background
       
   815     gc->BitBlt(TPoint(0,0), background);
       
   816     TInt textLeft = iTitles[iFirstDrawingTitleIndex]->TitleTextLengthInPixels() - 
       
   817         iFirstDrawingOffset;
       
   818     TInt drawingTitleIndex = iFirstDrawingTitleIndex;
       
   819     TInt drawingOffset(0);
       
   820 
       
   821 	// Main drawing loop. This loop runs as long as drawing area is not filled
       
   822     // if Scroll behaviour is slide, then short text drawn only once.
       
   823     FOREVER
       
   824         {
       
   825         TRect clipRect(TPoint(drawingPos,0), TPoint(iContentRect.Width(), iContentRect.Height()));
       
   826         if ( iTextFitInNewstickerRect )
       
   827             {
       
   828             clipRect.SetWidth( clipRect.Width()-drawingPos);
       
   829             }
       
   830         // if the rest text fits into visible area
       
   831      	if (textLeft <= iContentRect.Width() - drawingOffset)
       
   832      	    {
       
   833             gc->DrawText(iTitles[drawingTitleIndex]->TitleText(), 
       
   834                    clipRect,
       
   835                    iTextBaseline,
       
   836                    alignment);
       
   837 
       
   838      	    TInt drawnLength = iTitles[drawingTitleIndex]->TitleTextLengthInPixels() + KGap;
       
   839             drawingPos += drawnLength;
       
   840      	    drawingOffset = drawingPos;
       
   841             
       
   842             // Update title index, if needed
       
   843      	    drawingTitleIndex++;
       
   844      	    if(drawingTitleIndex >= iTitles.Count())
       
   845      	        {
       
   846      	        drawingTitleIndex = 0;
       
   847      	        if ( iAdapter->ScrollBehaviour() == CXnNewstickerAdapter::ESlide || iTextFitInNewstickerRect )
       
   848      	            {
       
   849      	            // what a dirty code!
       
   850      	            break;
       
   851      	            }
       
   852      	        }
       
   853             if(iSeparatorimage)
       
   854                 {
       
   855                 textLeft = 0;
       
   856                 }
       
   857             else
       
   858                 {
       
   859                 if (iTitles[drawingTitleIndex]->IsSvgTitle())
       
   860                     {
       
   861                     return;
       
   862                     }
       
   863                 else
       
   864                     {
       
   865                     textLeft = iTitles[drawingTitleIndex]->TitleTextLengthInPixels(); 
       
   866                     }
       
   867                 }
       
   868      	    }
       
   869         else 
       
   870             {
       
   871             // Clip the text if needed in alternate mode
       
   872             if  ( iAdapter->ScrollBehaviour() == CXnNewstickerAdapter::EAlternate )
       
   873                 {
       
   874                 HBufC* title = iTitles[drawingTitleIndex]->TitleText().AllocLC();
       
   875                 TPtr titlePtr = title->Des();
       
   876                 TInt maxLength = iContentRect.Width();
       
   877                 AknBidiTextUtils::ConvertToVisualAndClipL(
       
   878                         titlePtr, *iFont, maxLength, maxLength );                              
       
   879                 gc->DrawText( titlePtr, clipRect, iTextBaseline, alignment );
       
   880                 CleanupStack::PopAndDestroy( title );
       
   881                 }
       
   882             else
       
   883                 {
       
   884                 gc->DrawText(iTitles[drawingTitleIndex]->TitleText(), 
       
   885                         clipRect,
       
   886                         iTextBaseline,
       
   887                         alignment);
       
   888             
       
   889                 }            
       
   890      	    break;
       
   891             }
       
   892             
       
   893         if(iSeparatorimage)
       
   894      	    {
       
   895             TInt imageLeft = iSeparatorImageWidth - KGap;
       
   896             
       
   897             // if the rest of the image fits into visible area
       
   898  	        if (imageLeft <= iContentRect.Width() - drawingOffset)
       
   899  	            {
       
   900  	            gc->BitBltMasked(TPoint(drawingPos, 0), iSeparatorimage->Bitmap(), 
       
   901  	                TRect(TPoint(0,0), 
       
   902  	                iSeparatorimage->Bitmap()->SizeInPixels()), iSeparatorimage->Mask(), ETrue); 
       
   903                 drawingPos += iSeparatorImageWidth;
       
   904      	        drawingOffset = drawingPos;
       
   905                 textLeft = iTitles[drawingTitleIndex]->TitleTextLengthInPixels();
       
   906                 if (iTitles[drawingTitleIndex]->IsSvgTitle())
       
   907                     {
       
   908                     return;
       
   909                     }
       
   910  	            }
       
   911             else 
       
   912                 {
       
   913  	            gc->BitBltMasked(TPoint(drawingPos, 0), iSeparatorimage->Bitmap(), 
       
   914  	                TRect(TPoint(0,0), iSeparatorimage->Bitmap()->SizeInPixels()), 
       
   915  	                iSeparatorimage->Mask(), ETrue); 
       
   916                 break;
       
   917                 }
       
   918      	    }
       
   919 
       
   920         if( iAdapter->ScrollBehaviour() == CXnNewstickerAdapter::EAlternate || 
       
   921 			iAdapter->ScrollBehaviour() == CXnNewstickerAdapter::EScrollAlternate )
       
   922             {
       
   923             break;
       
   924             }
       
   925         }
       
   926     }
       
   927 
       
   928 // -----------------------------------------------------------------------------
       
   929 // CXnNewstickerControl::PrepareToDrawRtlL
       
   930 // (other items were commented in a header).
       
   931 // -----------------------------------------------------------------------------
       
   932 //
       
   933 void CXnNewstickerControl::PrepareToDrawRtlL()
       
   934     {
       
   935     CBitmapContext* gc = iAdapter->BufferGc();
       
   936     const CFbsBitmap* background = iAdapter->BackgroundBitmap();
       
   937     if(!gc || !background || !IsVisibleTitles() )
       
   938         {
       
   939         return;
       
   940         }
       
   941     if (iTitles[iFirstDrawingTitleIndex]->IsSvgTitle())
       
   942         {
       
   943         //  Show SVG title
       
   944         iAdapter->ShowSvgL();
       
   945         
       
   946     	// Just in case, draw background to d-buffer
       
   947         gc->BitBlt(TPoint(0,0), background);
       
   948         return;
       
   949         }
       
   950 
       
   951     CGraphicsContext::TTextAlign alignment = TextAlignment();
       
   952     if ( iTextFitInNewstickerRect || 
       
   953          iAdapter->ScrollBehaviour() == CXnNewstickerAdapter::EAlternate && iTitles.Count() == 1 )
       
   954         {
       
   955         SetBeginningState();
       
   956         iAdapter->StopL();
       
   957         }
       
   958     
       
   959 	// At first, draw background
       
   960     gc->BitBlt(TPoint(0,0), background);
       
   961     
       
   962     TInt textLeft = iFirstDrawingOffset - 
       
   963         iTitles[iFirstDrawingTitleIndex]->TitleTextLengthInPixels();
       
   964     if(textLeft >= iContentRect.Width() )
       
   965         {
       
   966         textLeft = 0;
       
   967         }
       
   968     TInt drawingTitleIndex = iFirstDrawingTitleIndex;
       
   969     TInt drawingOffset(iContentRect.iBr.iX);
       
   970     
       
   971     TRect clipRect(TPoint(0,0), TPoint(iFirstDrawingOffset, iContentRect.Height()));
       
   972     TInt clipWidth = clipRect.Width();
       
   973 	// Main drawing loop. This loop runs as long as drawing area is not filled
       
   974     FOREVER
       
   975         {
       
   976      	// if the rest text fits into visible area
       
   977      	if (textLeft <= drawingOffset)
       
   978      	    {
       
   979      	    HBufC* title = iTitles[drawingTitleIndex]->TitleText().AllocLC();
       
   980      	    TPtr titlePtr = title->Des();
       
   981 
       
   982      	    // convert to visual, do not clip
       
   983      	    TInt maxLength = iTitles[drawingTitleIndex]->TitleTextLengthInPixels();
       
   984      	    AknBidiTextUtils::ConvertToVisualAndClipL( titlePtr, *iFont,
       
   985      	                                               maxLength, maxLength );
       
   986    
       
   987             gc->DrawText( titlePtr, clipRect, iTextBaseline, alignment );
       
   988             CleanupStack::PopAndDestroy( title );
       
   989 
       
   990      	    TInt drawnLength = iTitles[drawingTitleIndex]->TitleTextLengthInPixels() + KGap;
       
   991             clipWidth -= drawnLength;
       
   992             clipRect.SetWidth(clipWidth);
       
   993             drawingOffset = clipRect.iBr.iX;
       
   994 
       
   995             // Update title index
       
   996      	    drawingTitleIndex++;
       
   997      	    if(drawingTitleIndex >= iTitles.Count())
       
   998      	        {
       
   999      	        drawingTitleIndex = 0;
       
  1000                 if ( iAdapter->ScrollBehaviour() == CXnNewstickerAdapter::ESlide || iTextFitInNewstickerRect)
       
  1001                     {
       
  1002                     // what a dirty code!
       
  1003                     break;
       
  1004                     }
       
  1005      	        }
       
  1006             if(iSeparatorimage)
       
  1007                 {
       
  1008                 textLeft = 0xfff;
       
  1009                 }
       
  1010             else
       
  1011                 {
       
  1012                 if (iTitles[drawingTitleIndex]->IsSvgTitle())
       
  1013                     {
       
  1014                     return;
       
  1015                     }
       
  1016                 else
       
  1017                     {
       
  1018                     textLeft = iTitles[drawingTitleIndex]->TitleTextLengthInPixels(); 
       
  1019                     }
       
  1020                 }
       
  1021      	    }
       
  1022         else 
       
  1023             {
       
  1024             // Clip the text if needed in alternate mode
       
  1025             if  ( iAdapter->ScrollBehaviour() == CXnNewstickerAdapter::EAlternate )
       
  1026                 {
       
  1027                 HBufC* title = iTitles[drawingTitleIndex]->TitleText().AllocLC();
       
  1028                 TPtr titlePtr = title->Des();
       
  1029                 TInt maxLength = iContentRect.Width();
       
  1030                 AknBidiTextUtils::ConvertToVisualAndClipL(
       
  1031                         titlePtr, *iFont, maxLength, maxLength );                              
       
  1032                 gc->DrawText( titlePtr, clipRect, iTextBaseline, alignment );
       
  1033                 CleanupStack::PopAndDestroy( title );
       
  1034                 }
       
  1035             else
       
  1036                 {
       
  1037                 gc->DrawText(iTitles[drawingTitleIndex]->TitleText(), clipRect, 
       
  1038                         iTextBaseline, alignment);
       
  1039                 }
       
  1040      	    break;
       
  1041             }
       
  1042 
       
  1043         if(iSeparatorimage)
       
  1044      	    {
       
  1045             TInt imageLeft = iSeparatorImageWidth - KGap;
       
  1046             
       
  1047             // if the rest of the image fits into visible area
       
  1048  	        if (imageLeft <= drawingOffset)
       
  1049  	            {
       
  1050  	            gc->BitBltMasked(TPoint(clipRect.iBr.iX - imageLeft, 0), 
       
  1051  	                iSeparatorimage->Bitmap(), TRect(TPoint(0,0), 
       
  1052  	                iSeparatorimage->Bitmap()->SizeInPixels()), 
       
  1053  	                iSeparatorimage->Mask(), ETrue);                
       
  1054                 clipWidth -= iSeparatorImageWidth;
       
  1055                 clipRect.SetWidth(clipWidth);
       
  1056                 drawingOffset = clipRect.iBr.iX;                
       
  1057                 textLeft = iTitles[drawingTitleIndex]->TitleTextLengthInPixels();
       
  1058                 if (iTitles[drawingTitleIndex]->IsSvgTitle())
       
  1059                     {
       
  1060                     return;
       
  1061                     }
       
  1062  	            }
       
  1063             else 
       
  1064                 {
       
  1065  	            gc->BitBltMasked(TPoint(clipRect.iBr.iX - imageLeft, 0), 
       
  1066  	                iSeparatorimage->Bitmap(), TRect(TPoint(0,0), 
       
  1067  	                iSeparatorimage->Bitmap()->SizeInPixels()), 
       
  1068  	                iSeparatorimage->Mask(), ETrue); 
       
  1069                 break;
       
  1070                 }
       
  1071      	    }
       
  1072      	    
       
  1073         if( iAdapter->ScrollBehaviour() == CXnNewstickerAdapter::EAlternate || 
       
  1074 			iAdapter->ScrollBehaviour() == CXnNewstickerAdapter::EScrollAlternate )     	    
       
  1075             {
       
  1076             break;
       
  1077             }     	    
       
  1078         }
       
  1079     }
       
  1080 
       
  1081 // -----------------------------------------------------------------------------
       
  1082 // CXnNewstickerControl::DoScrollL
       
  1083 // (other items were commented in a header).
       
  1084 // -----------------------------------------------------------------------------
       
  1085 //
       
  1086 void CXnNewstickerControl::DoScrollL()
       
  1087     {
       
  1088     //  If there are no titles, don't do anything.
       
  1089     if( !IsVisibleTitles() || iFirstDrawingTitleIndex < 0 )
       
  1090         {
       
  1091         return;
       
  1092         }
       
  1093     
       
  1094     iAdapter->DrawNow();
       
  1095     
       
  1096     if( iAdapter->ScrollBehaviour() == CXnNewstickerAdapter::EScroll ||
       
  1097         iAdapter->ScrollBehaviour() == CXnNewstickerAdapter::ESlide ||
       
  1098 		( iAdapter->ScrollBehaviour() == CXnNewstickerAdapter::EScrollAlternate &&
       
  1099 		  !CalculateCurrentTextFitInNewstickerRect() ) )
       
  1100         {    
       
  1101         iAdapter->SetTimerToScrolltime();             
       
  1102         iFirstDrawingOffset += iSpeed; // advance text
       
  1103         TInt titleLen = iTitles[iFirstDrawingTitleIndex]->TitleTextLengthInPixels() + 
       
  1104             iSeparatorImageWidth;
       
  1105 
       
  1106         // if 100% (or more) has been drawn update...
       
  1107         if ((iIsWestern && iFirstDrawingOffset >= titleLen) ||
       
  1108             (!iIsWestern && iFirstDrawingOffset - titleLen >= iContentRect.Width()))
       
  1109             {
       
  1110             iAdapter->TitleScrolled(iFirstDrawingTitleIndex);
       
  1111             iFirstDrawingTitleIndex = GetNextTitleWithContent( iFirstDrawingTitleIndex + 1);
       
  1112             if(iFirstDrawingTitleIndex >= iTitles.Count())
       
  1113      	        {
       
  1114      	        iFirstDrawingTitleIndex = GetNextTitleWithContent( 0 );
       
  1115                 if (iAdapter->ScrollBehaviour() == CXnNewstickerAdapter::ESlide )
       
  1116                     {
       
  1117                     if ( iIsWestern )
       
  1118                         {
       
  1119                         iFirstDrawingOffset = -(iContentRect.iBr.iX-iContentRect.iTl.iX-KGap);
       
  1120                         }
       
  1121                     else
       
  1122                         {
       
  1123                         iFirstDrawingOffset = 0;
       
  1124                         }
       
  1125                     }
       
  1126                 else
       
  1127                     {
       
  1128                     iFirstDrawingOffset -= titleLen + KGap;
       
  1129                     }
       
  1130      	        }
       
  1131             else
       
  1132                 {
       
  1133                 iFirstDrawingOffset -= titleLen + KGap;
       
  1134                 }
       
  1135             iCurrentTitleIndex = iFirstDrawingTitleIndex;
       
  1136 
       
  1137             if( iAdapter->ScrollBehaviour() == CXnNewstickerAdapter::EScrollAlternate &&
       
  1138 		        CalculateCurrentTextFitInNewstickerRect() )
       
  1139                 {
       
  1140                 MoveToNextL();
       
  1141                 }
       
  1142             }
       
  1143         // but if less than 100% and more than 75% has been drawn, update only current title index.
       
  1144         else if (((iIsWestern && iFirstDrawingOffset >= titleLen * 0.75) || 
       
  1145                   (!iIsWestern && iFirstDrawingOffset - titleLen >= iContentRect.iBr.iX * 0.75)) &&
       
  1146                    iFirstDrawingTitleIndex == iCurrentTitleIndex)
       
  1147             {
       
  1148             iCurrentTitleIndex++;
       
  1149      	    if(iCurrentTitleIndex >= iTitles.Count())
       
  1150      	        {
       
  1151      	        iCurrentTitleIndex = 0;
       
  1152      	        }
       
  1153      	    iCurrentTitleIndex = GetNextTitleWithContent( iCurrentTitleIndex );
       
  1154 
       
  1155             if( iAdapter->ScrollBehaviour() == CXnNewstickerAdapter::EScrollAlternate &&
       
  1156 		        CalculateCurrentTextFitInNewstickerRect() )
       
  1157                 {
       
  1158                 MoveToNextL();
       
  1159                 }
       
  1160             }
       
  1161         }
       
  1162     else if( iAdapter->ScrollBehaviour() == CXnNewstickerAdapter::EScrollAlternate &&
       
  1163 		     CalculateCurrentTextFitInNewstickerRect() )
       
  1164         {
       
  1165         iAdapter->SetTimerToDisplaytime();
       
  1166         MoveToNextL();
       
  1167         }
       
  1168     else
       
  1169         {
       
  1170         MoveToNextL();
       
  1171         }        
       
  1172     }
       
  1173 
       
  1174 // -----------------------------------------------------------------------------
       
  1175 // CXnNewstickerControl::Draw
       
  1176 // (other items were commented in a header).
       
  1177 // -----------------------------------------------------------------------------
       
  1178 //
       
  1179 void CXnNewstickerControl::Draw()
       
  1180     {
       
  1181     if( IsVisibleTitles() > 0 ) 
       
  1182         {
       
  1183         if( iIsWestern )
       
  1184             {
       
  1185             TRAP_IGNORE( PrepareToDrawLtrL() );
       
  1186             }
       
  1187         else
       
  1188             {
       
  1189             TRAP_IGNORE( PrepareToDrawRtlL() );
       
  1190             }
       
  1191         }    
       
  1192     else
       
  1193         {
       
  1194         CBitmapContext* gc = iAdapter->BufferGc();
       
  1195         const CFbsBitmap* background = iAdapter->BackgroundBitmap();
       
  1196         if ( gc && background )
       
  1197             {            
       
  1198             gc->BitBlt(TPoint(0,0), background);
       
  1199             }
       
  1200         }
       
  1201     }
       
  1202 
       
  1203 // -----------------------------------------------------------------------------
       
  1204 // CXnNewstickerControl::DrawStatic
       
  1205 // (other items were commented in a header).
       
  1206 // -----------------------------------------------------------------------------
       
  1207 //
       
  1208 void CXnNewstickerControl::DrawStatic()
       
  1209     {
       
  1210     // draw to buffer gc
       
  1211     CBitmapContext* gc = iAdapter->BufferGc();
       
  1212     const CFbsBitmap* background = iAdapter->BackgroundBitmap();
       
  1213     if( !gc || !background || !IsVisibleTitles() )
       
  1214         {
       
  1215         return;
       
  1216         }
       
  1217     gc->BitBlt( TPoint(0,0), background );
       
  1218     
       
  1219     // Get the last title
       
  1220     TInt index = GetNextTitleWithContent( iTitles.Count() - 1, ETrue );
       
  1221     const TDesC& title = Title( index );
       
  1222     
       
  1223     // truncate text if needed
       
  1224     HBufC* visualText = HBufC::New(title.Length() + KAknBidiExtraSpacePerLine);
       
  1225     if (visualText)
       
  1226         {
       
  1227         TPtr visualTextPtr(visualText->Des());
       
  1228         TInt maxLength = iContentRect.Width();
       
  1229         AknBidiTextUtils::ConvertToVisualAndClip(
       
  1230                      title, visualTextPtr, *iFont, maxLength, maxLength );
       
  1231             
       
  1232         TRect blitRect( 0, 0, iContentRect.Width(), iContentRect.Height() );
       
  1233         gc->DrawText( *visualText, blitRect, iTextBaseline, TextAlignment() );
       
  1234         delete visualText;
       
  1235         }
       
  1236     }
       
  1237 
       
  1238 // -----------------------------------------------------------------------------
       
  1239 // CXnNewstickerControl::SetBeginningState
       
  1240 // (other items were commented in a header).
       
  1241 // -----------------------------------------------------------------------------
       
  1242 //
       
  1243 void CXnNewstickerControl::SetBeginningState()
       
  1244     {
       
  1245     iFirstDrawingOffset = 0;
       
  1246     if(!iIsWestern)
       
  1247         {
       
  1248         iFirstDrawingOffset = iContentRect.Width();
       
  1249         }
       
  1250     }
       
  1251 
       
  1252 // -----------------------------------------------------------------------------
       
  1253 // CXnNewstickerControl::SetScrollLooping
       
  1254 // (other items were commented in a header).
       
  1255 // -----------------------------------------------------------------------------
       
  1256 //
       
  1257 void CXnNewstickerControl::SetScrollLooping( TBool aLoop )
       
  1258     {
       
  1259     iScrollLooping = aLoop;
       
  1260     }
       
  1261 
       
  1262 // -----------------------------------------------------------------------------
       
  1263 // CXnNewstickerControl::ScrollLooping
       
  1264 // (other items were commented in a header).
       
  1265 // -----------------------------------------------------------------------------
       
  1266 //
       
  1267 TBool CXnNewstickerControl::ScrollLooping()
       
  1268     {
       
  1269     return iScrollLooping;
       
  1270     }
       
  1271 
       
  1272 // -----------------------------------------------------------------------------
       
  1273 // CXnNewstickerControl::TextFitInNewstickerRect
       
  1274 // (other items were commented in a header).
       
  1275 // -----------------------------------------------------------------------------
       
  1276 //
       
  1277 TBool CXnNewstickerControl::TextFitInNewstickerRect()
       
  1278     {
       
  1279     return iTextFitInNewstickerRect; 
       
  1280     }
       
  1281 
       
  1282 // -----------------------------------------------------------------------------
       
  1283 // CXnNewstickerControl::CalculateTextFitInNewstickerRect
       
  1284 // (other items were commented in a header).
       
  1285 // -----------------------------------------------------------------------------
       
  1286 //
       
  1287 TBool CXnNewstickerControl::CalculateTextFitInNewstickerRect()
       
  1288     {
       
  1289     if ( iAdapter->ScrollBehaviour() == CXnNewstickerAdapter::ESlide &&
       
  1290          iTitles.Count() == 1 )
       
  1291         {
       
  1292         const TInt count = iTitles.Count();
       
  1293         TInt textWidth=0;
       
  1294         const TInt rectWidth = iContentRect.Width();
       
  1295         for (TInt i=0; i<count && textWidth<rectWidth;i++)
       
  1296             {
       
  1297             textWidth += iTitles[i]->TitleTextLengthInPixels();
       
  1298             }
       
  1299         iTextFitInNewstickerRect = (textWidth<rectWidth);
       
  1300         }
       
  1301     else
       
  1302         {
       
  1303         iTextFitInNewstickerRect = EFalse;
       
  1304         }
       
  1305     return iTextFitInNewstickerRect;
       
  1306     }
       
  1307 
       
  1308 // -----------------------------------------------------------------------------
       
  1309 // CXnNewstickerControl::CalculateCurrentTextFitInNewstickerRect
       
  1310 // (other items were commented in a header).
       
  1311 // -----------------------------------------------------------------------------
       
  1312 //
       
  1313 TBool CXnNewstickerControl::CalculateCurrentTextFitInNewstickerRect()
       
  1314     {
       
  1315     if ( iAdapter->ScrollBehaviour() == CXnNewstickerAdapter::EScrollAlternate )
       
  1316         {
       
  1317         const TInt count = iTitles.Count();
       
  1318         TInt textWidth=0;
       
  1319         const TInt rectWidth = iContentRect.Width();
       
  1320         if( iCurrentTitleIndex < count )
       
  1321             {
       
  1322             textWidth = iTitles[iCurrentTitleIndex]->TitleTextLengthInPixels();
       
  1323             }
       
  1324         return ( textWidth < rectWidth );
       
  1325         }
       
  1326     return EFalse;
       
  1327     }
       
  1328 
       
  1329 // -----------------------------------------------------------------------------
       
  1330 // CXnNewstickerControl::SetTextAlignment
       
  1331 // (other items were commented in a header).
       
  1332 // -----------------------------------------------------------------------------
       
  1333 //
       
  1334 void CXnNewstickerControl::SetTextAlignment(TInt aAlignment)
       
  1335     {
       
  1336     iTextAlignment = aAlignment;
       
  1337     }
       
  1338 
       
  1339 // -----------------------------------------------------------------------------
       
  1340 // CXnNewstickerControl::TextAlignment
       
  1341 // if title fits to the drawing rect and scrolling behaviour is ESlide then 
       
  1342 // use alignment value 
       
  1343 // if scroll behaviour is alternate then use alignment value
       
  1344 // otherwise return ELeft in western and ERight on AH
       
  1345 // -----------------------------------------------------------------------------
       
  1346 //
       
  1347 CGraphicsContext::TTextAlign CXnNewstickerControl::TextAlignment()
       
  1348     {
       
  1349     CGraphicsContext::TTextAlign alignment = iIsWestern ? CGraphicsContext::ELeft : CGraphicsContext::ERight;
       
  1350     
       
  1351     if ( iTextFitInNewstickerRect || iAdapter->ScrollBehaviour() == CXnNewstickerAdapter::EAlternate ||
       
  1352          ( iAdapter->ScrollBehaviour() == CXnNewstickerAdapter::EScrollAlternate && 
       
  1353            CalculateCurrentTextFitInNewstickerRect() ) )
       
  1354         {
       
  1355         switch( iTextAlignment )
       
  1356             {
       
  1357             default:
       
  1358             case ELayoutAlignLeft:
       
  1359                 alignment = CGraphicsContext::ELeft;
       
  1360                 break;
       
  1361             case ELayoutAlignRight:
       
  1362                 alignment = CGraphicsContext::ERight;
       
  1363                 break;
       
  1364             case ELayoutAlignCenter:
       
  1365                 alignment = CGraphicsContext::ECenter;
       
  1366                 break;
       
  1367             }
       
  1368         }
       
  1369     return alignment;
       
  1370     }
       
  1371 
       
  1372 TInt CXnNewstickerControl::GetNextTitleWithContent( TInt aStartSearch, TBool aBackwards )
       
  1373     {
       
  1374     TInt dir = 1;
       
  1375     if ( aBackwards )
       
  1376         {
       
  1377         dir = -1;
       
  1378         }
       
  1379     for( TInt i = aStartSearch; i < iTitles.Count() && i >= 0; i += dir )
       
  1380         {
       
  1381         if ( iTitles[i]->TitleTextLengthInPixels() != 0 )
       
  1382             {
       
  1383             return i;
       
  1384             }
       
  1385         }
       
  1386     return aStartSearch;
       
  1387     }
       
  1388 
       
  1389 TBool CXnNewstickerControl::IsVisibleTitles()
       
  1390     {
       
  1391     for( TInt i = 0; i < iTitles.Count() ; ++i )
       
  1392         {
       
  1393         if ( iTitles[i]->TitleTextLengthInPixels() != 0 )
       
  1394             {
       
  1395             return ETrue;
       
  1396             }
       
  1397         }
       
  1398     return EFalse;
       
  1399     }
       
  1400 
       
  1401 
       
  1402 //  End of File