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