javauis/lcdui_akn/lcdui/src/CMIDTicker.cpp
branchRCL_3
changeset 19 04becd199f91
child 60 6c158198356e
equal deleted inserted replaced
16:f5050f1da672 19:04becd199f91
       
     1 /*
       
     2 * Copyright (c) 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:  Implementation of the Ticker component
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <eikenv.h>
       
    20 #include <coecntrl.h>
       
    21 #include <coeccntx.h>
       
    22 #include <coecobs.h>
       
    23 // needed API for iAvkonAppUi
       
    24 #include <aknappui.h>
       
    25 #include <AknsUtils.h>
       
    26 #include <aknconsts.h>
       
    27 
       
    28 //#include <aknlayoutdef.h>
       
    29 //#include <aknlayout.lag>
       
    30 // CAknLayoutFont API for font layouting
       
    31 #include <AknLayoutFont.h>
       
    32 
       
    33 #include <aknenv.h>
       
    34 // CAknIndicatorContainer API for updating text capacity indicator
       
    35 #include <AknIndicatorContainer.h>
       
    36 // MAknEditingStateIndicator API for updating text capacity indicator
       
    37 // and setting state to edit indicators
       
    38 #include <aknEditStateIndicator.h>
       
    39 #include <aknnavi.h>
       
    40 // CAknNavigationDecorator* iNaviDecorator
       
    41 #include <aknnavide.h>
       
    42 
       
    43 #include <AknsDrawUtils.h>
       
    44 #include <j2me/jdebug.h>
       
    45 #include "CMIDTicker.h"
       
    46 // needed for setting and removing displayables (iDisplayableRArray)
       
    47 #include "CMIDDisplayable.h"
       
    48 // CMIDUtils::MapJavaToETextChars in CMIDScrollingText::SetTextL
       
    49 #include "CMIDUtils.h"
       
    50 #include "CMIDUIManager.h"
       
    51 
       
    52 /**
       
    53  * To enable ticker tracing, uncomment the follwing two lines and link
       
    54  * to estlib.lib:
       
    55  *
       
    56  *#include <stdio.h>
       
    57  *#define TRACE_TICKER 1
       
    58  */
       
    59 
       
    60 /** Time between each tick.*/
       
    61 const TInt KTickPeriod = 40000;
       
    62 
       
    63 /** Scrolling width in pixels where increment increases*/
       
    64 const TInt KScrollingWidthLimit = 200;
       
    65 
       
    66 /** Increment values for two different scrolling widths*/
       
    67 const TInt KOnePixel = 1;
       
    68 const TInt KTwoPixels = 2;
       
    69 
       
    70 _LIT(KLeftSquareBracket, "[");
       
    71 _LIT(KRightSquareBracket, "]");
       
    72 _LIT(KTextCapacity, "(999) ");
       
    73 
       
    74 _LIT(KLeftSmalllBracket, "(");
       
    75 _LIT(KRightSmallBracket, ")");
       
    76 
       
    77 #ifdef _DEBUG
       
    78 #define DEBUG_ARG(x) x
       
    79 #else
       
    80 #define DEBUG_ARG(x)
       
    81 #endif
       
    82 
       
    83 //
       
    84 // Private helper functions
       
    85 //
       
    86 // ---------------------------------------------------------------------------
       
    87 //
       
    88 // ---------------------------------------------------------------------------
       
    89 //
       
    90 void CleanupTicker(TAny* aTicker)
       
    91 {
       
    92     static_cast< CMIDTicker* >(aTicker)->Dispose();
       
    93 }
       
    94 
       
    95 
       
    96 // ---------------------------------------------------------------------------
       
    97 // Return the navi pane container. The method trapped should not leave.
       
    98 // ---------------------------------------------------------------------------
       
    99 //
       
   100 CAknNavigationControlContainer* NaviContainerL()
       
   101 {
       
   102     CEikStatusPane *sp = iAvkonAppUi->StatusPane();
       
   103     CAknNavigationControlContainer* naviC =
       
   104         static_cast<CAknNavigationControlContainer*>(sp->ControlL(TUid::Uid(EEikStatusPaneUidNavi)));
       
   105 
       
   106     return naviC;
       
   107 }
       
   108 
       
   109 // ---------------------------------------------------------------------------
       
   110 // Return a text layout defined in the platform LAF
       
   111 // for text to be shown in the navi pane. According to the
       
   112 // type of navi pane control the text layout may be different.
       
   113 // We have chosen to use the same layout as the edit indicator
       
   114 // text (the text showing how many chars are left in an editor).
       
   115 // To use the layout used by navi pane labels use
       
   116 // Navi_pane_texts_Line_1. This layout information determines the
       
   117 // font and the text color. Text positioning is not taken from
       
   118 // layout, the text is vertically centered and scrolled horizontally
       
   119 // instead, h aligned to the left or right of the navi pane according
       
   120 // to the directionality.
       
   121 // ---------------------------------------------------------------------------
       
   122 //
       
   123 const TAknTextLineLayout Layout()
       
   124 {
       
   125     return AknLayout::Small_status_pane_texts_Line_1(0);
       
   126 }
       
   127 
       
   128 // ---------------------------------------------------------------------------
       
   129 // Return the text alignment according to locale alignment
       
   130 // ---------------------------------------------------------------------------
       
   131 //
       
   132 CGraphicsContext::TTextAlign TextAlign()
       
   133 {
       
   134     return AknLayoutUtils::LayoutMirrored() ? CGraphicsContext::ERight : CGraphicsContext::ELeft;
       
   135 }
       
   136 
       
   137 //
       
   138 // class CMIDTickerController
       
   139 //
       
   140 
       
   141 // ---------------------------------------------------------------------------
       
   142 //
       
   143 // ---------------------------------------------------------------------------
       
   144 //
       
   145 CMIDNaviPaneController* CMIDNaviPaneController::NewL()
       
   146 {
       
   147     CMIDNaviPaneController* self=new(ELeave) CMIDNaviPaneController();
       
   148     CleanupStack::PushL(self);
       
   149     self->ConstructL();
       
   150     CleanupStack::Pop(self);
       
   151     return self;
       
   152 }
       
   153 
       
   154 // ---------------------------------------------------------------------------
       
   155 //
       
   156 // ---------------------------------------------------------------------------
       
   157 //
       
   158 CMIDNaviPaneController::~CMIDNaviPaneController()
       
   159 {
       
   160     delete iTickerTimer;
       
   161     iTickerTimer = NULL;
       
   162     delete iEditCapacityText;
       
   163     iTickerObservers.Close();
       
   164 }
       
   165 
       
   166 // ---------------------------------------------------------------------------
       
   167 //
       
   168 // ---------------------------------------------------------------------------
       
   169 //
       
   170 CMIDNaviPaneController::CMIDNaviPaneController()
       
   171 {
       
   172 }
       
   173 
       
   174 // ---------------------------------------------------------------------------
       
   175 //
       
   176 // ---------------------------------------------------------------------------
       
   177 //
       
   178 void CMIDNaviPaneController::ConstructL()
       
   179 {
       
   180 }
       
   181 
       
   182 // ---------------------------------------------------------------------------
       
   183 //
       
   184 // ---------------------------------------------------------------------------
       
   185 //
       
   186 void CMIDNaviPaneController::UpdateTextInputIndicatorL(TInt aCount)
       
   187 {
       
   188     delete iEditCapacityText;
       
   189     iEditCapacityText = NULL;
       
   190 
       
   191     if (aCount >= 0 && aCount <= 999)
       
   192     {
       
   193         const CFont* font = AknLayoutUtils::FontFromId(Layout().FontId());
       
   194         TBuf<10> text;
       
   195 
       
   196         text.Append(KLeftSmalllBracket);
       
   197         text.AppendNum(aCount);
       
   198         text.Append(KRightSmallBracket);
       
   199 
       
   200         // set text localized (non Latin numbers)
       
   201         AknTextUtils::LanguageSpecificNumberConversion(text);
       
   202 
       
   203         iEditCapacityText = TBidiText::NewL(text,1);
       
   204         iEditCapacityText->WrapText(font->TextWidthInPixels(KTextCapacity), *font, NULL);
       
   205 
       
   206         AddEditCapacityTextToNaviPaneL();
       
   207     }
       
   208     else
       
   209     {
       
   210         // to prevent panic if state indicator is NULL (it can happen when 3rd party FEP is active)
       
   211         MAknEditingStateIndicator* indicator = CAknEnv::Static()->EditingStateIndicator();
       
   212         if (indicator)
       
   213         {
       
   214             indicator->IndicatorContainer()->SetIndicatorState(
       
   215                 TUid::Uid(EAknNaviPaneEditorIndicatorMessageLength),
       
   216                 EAknIndicatorStateOff);
       
   217         }
       
   218     }
       
   219 }
       
   220 
       
   221 // ---------------------------------------------------------------------------
       
   222 //
       
   223 // ---------------------------------------------------------------------------
       
   224 //
       
   225 TBidiText* CMIDNaviPaneController::EditCapacityText() const
       
   226 {
       
   227     return iEditCapacityText;
       
   228 }
       
   229 
       
   230 // ---------------------------------------------------------------------------
       
   231 //
       
   232 // ---------------------------------------------------------------------------
       
   233 //
       
   234 void CMIDNaviPaneController::AddTickerObserverL(
       
   235     MMIDTickerObserver* aObserver)
       
   236 {
       
   237     ASSERT(aObserver);
       
   238     if (iTickerObservers.Find(aObserver) == KErrNotFound)
       
   239     {
       
   240         User::LeaveIfError(iTickerObservers.Append(aObserver));
       
   241     }
       
   242 }
       
   243 
       
   244 // ---------------------------------------------------------------------------
       
   245 //
       
   246 // ---------------------------------------------------------------------------
       
   247 //
       
   248 void CMIDNaviPaneController::RemoveTickerObserver(
       
   249     MMIDTickerObserver* aObserver)
       
   250 {
       
   251     ASSERT(aObserver);
       
   252     TInt index = iTickerObservers.Find(aObserver);
       
   253     if (index != KErrNotFound)
       
   254     {
       
   255         iTickerObservers.Remove(index);
       
   256     }
       
   257 }
       
   258 
       
   259 // ---------------------------------------------------------------------------
       
   260 //
       
   261 // ---------------------------------------------------------------------------
       
   262 //
       
   263 void CMIDNaviPaneController::SetTickerL(CMIDTicker* aTicker)
       
   264 {
       
   265     if (!iTickerTimer && !aTicker)
       
   266     {
       
   267         // CMIDTickerTimer instance is created only when
       
   268         // a ticker object is set
       
   269         return;
       
   270     }
       
   271     if (!iTickerTimer)
       
   272     {
       
   273         iTickerTimer = CMIDTickerTimer::NewL(this);
       
   274     }
       
   275     iTickerTimer->SetTickerL(aTicker);
       
   276 }
       
   277 
       
   278 
       
   279 // ---------------------------------------------------------------------------
       
   280 //
       
   281 // ---------------------------------------------------------------------------
       
   282 //
       
   283 void CMIDNaviPaneController::ShowTickerL(TBool aShow)
       
   284 {
       
   285     if (iTickerTimer)
       
   286     {
       
   287         iTickerTimer->ShowTickerL(aShow);
       
   288     }
       
   289 }
       
   290 
       
   291 // ---------------------------------------------------------------------------
       
   292 //
       
   293 // ---------------------------------------------------------------------------
       
   294 //
       
   295 void CMIDNaviPaneController::PauseTickerL(
       
   296     TInt aInterval, MMIDTickerObserver* aPausingObserver)
       
   297 {
       
   298     if (aInterval > 0)
       
   299     {
       
   300         // Set last observer to pause the ticker
       
   301         iPausingObserver = aPausingObserver;
       
   302     }
       
   303     if (iTickerTimer)
       
   304     {
       
   305         iTickerTimer->PauseTickerL(aInterval, aPausingObserver);
       
   306     }
       
   307 }
       
   308 
       
   309 // ---------------------------------------------------------------------------
       
   310 //
       
   311 // ---------------------------------------------------------------------------
       
   312 //
       
   313 void CMIDNaviPaneController::TickerChangedL(CMIDTicker* aTicker, TTickerEvent aEvent)
       
   314 {
       
   315     if (iTickerTimer)
       
   316     {
       
   317         iTickerTimer->TickerChangedL(aTicker, aEvent);
       
   318     }
       
   319 }
       
   320 
       
   321 // ---------------------------------------------------------------------------
       
   322 //
       
   323 // ---------------------------------------------------------------------------
       
   324 //
       
   325 void CMIDNaviPaneController::LayoutTickerL()
       
   326 {
       
   327     if (iTickerTimer)
       
   328     {
       
   329         iTickerTimer->LayoutTickerL();
       
   330     }
       
   331 }
       
   332 
       
   333 // ---------------------------------------------------------------------------
       
   334 //
       
   335 // ---------------------------------------------------------------------------
       
   336 //
       
   337 void CMIDNaviPaneController::ResetTickerScrollingSpeedL()
       
   338 {
       
   339     if (iTickerTimer)
       
   340     {
       
   341         iTickerTimer->ResetScrollingSpeedL();
       
   342     }
       
   343 }
       
   344 
       
   345 // ---------------------------------------------------------------------------
       
   346 //
       
   347 // ---------------------------------------------------------------------------
       
   348 //
       
   349 void CMIDNaviPaneController::NotifyTickerObservers(TBool aShowing)
       
   350 {
       
   351     TInt numObservers = iTickerObservers.Count();
       
   352     for (TInt index = 0; index < numObservers; index++)
       
   353     {
       
   354         iTickerObservers[ index ]->TickerShowing(aShowing);
       
   355     }
       
   356 }
       
   357 
       
   358 // ---------------------------------------------------------------------------
       
   359 //
       
   360 // ---------------------------------------------------------------------------
       
   361 //
       
   362 void CMIDNaviPaneController::AddEditCapacityTextToNaviPaneL()
       
   363 {
       
   364     if (iEditCapacityText != NULL &&
       
   365             (!iTickerTimer ||
       
   366              !iTickerTimer->iEnabled ||
       
   367              !iTickerTimer->iTicker))
       
   368     {
       
   369         // to prevent panic if state indicator is NULL (it can happen when 3rd party FEP is active)
       
   370         MAknEditingStateIndicator* indicator = CAknEnv::Static()->EditingStateIndicator();
       
   371         if (indicator)
       
   372         {
       
   373             indicator->IndicatorContainer()->SetIndicatorState(
       
   374                 TUid::Uid(EAknNaviPaneEditorIndicatorMessageLength), EAknIndicatorStateOn);
       
   375             indicator->IndicatorContainer()->SetIndicatorValueL(
       
   376                 TUid::Uid(EAknNaviPaneEditorIndicatorMessageLength), iEditCapacityText->Text());
       
   377         }
       
   378     }
       
   379 }
       
   380 
       
   381 
       
   382 // ---------------------------------------------------------------------------
       
   383 //
       
   384 // ---------------------------------------------------------------------------
       
   385 //
       
   386 CMIDTickerTimer* CMIDTickerTimer::NewL(CMIDNaviPaneController* aController)
       
   387 {
       
   388     CMIDTickerTimer* self=new(ELeave) CMIDTickerTimer(aController);
       
   389     CleanupStack::PushL(self);
       
   390     self->ConstructL();
       
   391     CleanupStack::Pop(self);
       
   392     return self;
       
   393 }
       
   394 
       
   395 // ---------------------------------------------------------------------------
       
   396 //
       
   397 // ---------------------------------------------------------------------------
       
   398 //
       
   399 CMIDTickerTimer::~CMIDTickerTimer()
       
   400 {
       
   401     DEBUG("CMIDTickerTimer::~CMIDTickerTimer - calling StopL");
       
   402     TRAPD(ignore,StopL());
       
   403     if (ignore != KErrNone)
       
   404     {
       
   405         DEBUG_INT("CMIDTickerTimer::~CMIDTickerTimer - Exception from StopL. Error = %d", ignore);
       
   406     }
       
   407 }
       
   408 
       
   409 // ---------------------------------------------------------------------------
       
   410 //
       
   411 // ---------------------------------------------------------------------------
       
   412 //
       
   413 CMIDTickerTimer::CMIDTickerTimer(CMIDNaviPaneController* aCtrl)
       
   414         : CTimer(CActive::EPriorityHigh)
       
   415         , iCtrl(aCtrl)
       
   416         , iTicker(NULL)
       
   417         , iEnabled(EFalse)
       
   418         , iIncrement(KOnePixel)
       
   419 {
       
   420 }
       
   421 
       
   422 // ---------------------------------------------------------------------------
       
   423 //
       
   424 // ---------------------------------------------------------------------------
       
   425 //
       
   426 void CMIDTickerTimer::ConstructL()
       
   427 {
       
   428     CTimer::ConstructL();
       
   429     ResetScrollingSpeedL();
       
   430     CActiveScheduler::Add(this);
       
   431 }
       
   432 
       
   433 
       
   434 // ---------------------------------------------------------------------------
       
   435 //
       
   436 // ---------------------------------------------------------------------------
       
   437 //
       
   438 void CMIDTickerTimer::RunL()
       
   439 {
       
   440     if (iIsPaused)
       
   441     {
       
   442         iIsPaused = EFalse;
       
   443         StartL();
       
   444         return;
       
   445     }
       
   446 
       
   447     if (iTicker)
       
   448     {
       
   449         iTicker->TickL(iIncrement);
       
   450         Kick();
       
   451     }
       
   452 }
       
   453 
       
   454 // ---------------------------------------------------------------------------
       
   455 //
       
   456 // ---------------------------------------------------------------------------
       
   457 //
       
   458 void CMIDTickerTimer::TickerChangedL(
       
   459     CMIDTicker* aTicker, CMIDNaviPaneController::TTickerEvent aEvent)
       
   460 {
       
   461     ASSERT(aTicker == iTicker);
       
   462     (void)aTicker; // Just to suppress warning in release build
       
   463     switch (aEvent)
       
   464     {
       
   465     case CMIDNaviPaneController::ENone:
       
   466     case CMIDNaviPaneController::EModelChanged:
       
   467         // ignore
       
   468         break;
       
   469     case CMIDNaviPaneController::ETextChanged:
       
   470         break;
       
   471 
       
   472     case CMIDNaviPaneController::EPositionChanged:
       
   473         iTicker->RenderL();
       
   474         break;
       
   475     }
       
   476 }
       
   477 
       
   478 
       
   479 // ---------------------------------------------------------------------------
       
   480 //
       
   481 // ---------------------------------------------------------------------------
       
   482 //
       
   483 void CMIDTickerTimer::ShowTickerL(TBool aShow)
       
   484 {
       
   485     if (aShow)
       
   486     {
       
   487         StartL();
       
   488     }
       
   489     else
       
   490     {
       
   491         StopL();
       
   492     }
       
   493 }
       
   494 
       
   495 // ---------------------------------------------------------------------------
       
   496 //
       
   497 // ---------------------------------------------------------------------------
       
   498 //
       
   499 void CMIDTickerTimer::SetTickerL(CMIDTicker* aTicker)
       
   500 {
       
   501     if (iTicker != aTicker)
       
   502     {
       
   503         if (iTicker)
       
   504         {
       
   505             iTicker->StopL();
       
   506             iTicker->SetController(NULL);
       
   507             iTicker->RemoveRef();
       
   508         }
       
   509 
       
   510         iTicker = aTicker;
       
   511 
       
   512         if (iTicker)
       
   513         {
       
   514             iTicker->AddRef();
       
   515             iTicker->SetController(iCtrl);
       
   516         }
       
   517     }
       
   518     else
       
   519     {
       
   520         if (iTicker)
       
   521         {
       
   522             iTicker->PauseL();
       
   523         }
       
   524     }
       
   525 
       
   526     // If the ticker is paused for textfield and textbox and displayable is changed
       
   527     // cancel the pause timer and  start the ticker
       
   528     if (iIsPaused)
       
   529     {
       
   530         Cancel();
       
   531     }
       
   532 
       
   533     CheckedStart();
       
   534 }
       
   535 
       
   536 // ---------------------------------------------------------------------------
       
   537 //
       
   538 // ---------------------------------------------------------------------------
       
   539 //
       
   540 void CMIDTickerTimer::PauseTickerL(TInt aInterval, MMIDTickerObserver* aPausingObserver)
       
   541 {
       
   542     if (aInterval <= 0)
       
   543     {
       
   544         if (iCtrl->iPausingObserver == aPausingObserver)
       
   545         { //only last requesting pausing observer can annulate request
       
   546             iIsPaused = EFalse;
       
   547             StartL();
       
   548         }
       
   549     }
       
   550     else
       
   551     {
       
   552         PauseL();
       
   553         After(aInterval);
       
   554         iIsPaused = ETrue;
       
   555     }
       
   556 }
       
   557 
       
   558 // ---------------------------------------------------------------------------
       
   559 //
       
   560 // ---------------------------------------------------------------------------
       
   561 //
       
   562 void CMIDTickerTimer::StartL()
       
   563 {
       
   564     Cancel();
       
   565 
       
   566     iEnabled = ETrue;
       
   567     iCtrl->NotifyTickerObservers(iEnabled && iTicker);
       
   568 
       
   569     if (iTicker)
       
   570     {
       
   571         iTicker->StartL();
       
   572     }
       
   573 
       
   574     iCtrl->iPausingObserver = NULL;
       
   575     iIsPaused = EFalse;
       
   576 
       
   577     CheckedStart();
       
   578 }
       
   579 
       
   580 // ---------------------------------------------------------------------------
       
   581 //
       
   582 // ---------------------------------------------------------------------------
       
   583 //
       
   584 void CMIDTickerTimer::PauseL()
       
   585 {
       
   586     Cancel();
       
   587 
       
   588     iEnabled = EFalse;
       
   589     iCtrl->NotifyTickerObservers(iEnabled);
       
   590 
       
   591     if (iTicker)
       
   592     {
       
   593         iTicker->PauseL();
       
   594     }
       
   595 
       
   596     iCtrl->AddEditCapacityTextToNaviPaneL();
       
   597 }
       
   598 
       
   599 // ---------------------------------------------------------------------------
       
   600 //
       
   601 // ---------------------------------------------------------------------------
       
   602 //
       
   603 void CMIDTickerTimer::StopL()
       
   604 {
       
   605     iEnabled = EFalse;
       
   606     iCtrl->NotifyTickerObservers(iEnabled);
       
   607 
       
   608     if (iTicker)
       
   609     {
       
   610         iTicker->StopL();
       
   611     }
       
   612 
       
   613     iCtrl->AddEditCapacityTextToNaviPaneL();
       
   614 
       
   615     Cancel();
       
   616 }
       
   617 
       
   618 // ---------------------------------------------------------------------------
       
   619 //
       
   620 // ---------------------------------------------------------------------------
       
   621 //
       
   622 void CMIDTickerTimer::CheckedStart()
       
   623 {
       
   624     if (!iEnabled)
       
   625     {
       
   626         return;
       
   627     }
       
   628     if (NULL == iTicker)
       
   629     {
       
   630         return;
       
   631     }
       
   632 
       
   633     if (!IsActive())
       
   634     {
       
   635         Kick();
       
   636     }
       
   637 }
       
   638 
       
   639 // ---------------------------------------------------------------------------
       
   640 //
       
   641 // ---------------------------------------------------------------------------
       
   642 //
       
   643 void CMIDTickerTimer::Kick()
       
   644 {
       
   645     ASSERT(iEnabled);
       
   646     ASSERT(iTicker);
       
   647     if (!IsActive())
       
   648     {
       
   649         After(KTickPeriod);
       
   650     }
       
   651 }
       
   652 
       
   653 // ---------------------------------------------------------------------------
       
   654 //
       
   655 // ---------------------------------------------------------------------------
       
   656 //
       
   657 void CMIDTickerTimer::LayoutTickerL()
       
   658 {
       
   659     ResetScrollingSpeedL();
       
   660     if (iTicker)
       
   661     {
       
   662         iTicker->LayoutL();
       
   663     }
       
   664 }
       
   665 
       
   666 // ---------------------------------------------------------------------------
       
   667 //
       
   668 // ---------------------------------------------------------------------------
       
   669 //
       
   670 void CMIDTickerTimer::ResetScrollingSpeedL()
       
   671 {
       
   672     if (CMIDScrollingText::ScrollingWidthL() <= KScrollingWidthLimit)
       
   673     {
       
   674         iIncrement = KOnePixel;
       
   675     }
       
   676     else
       
   677     {
       
   678         iIncrement = KTwoPixels;
       
   679     }
       
   680 }
       
   681 
       
   682 //
       
   683 // class CMIDTicker
       
   684 //
       
   685 // ---------------------------------------------------------------------------
       
   686 //
       
   687 // ---------------------------------------------------------------------------
       
   688 //
       
   689 MMIDTicker* CMIDTicker::NewL(const TDesC& aText)
       
   690 {
       
   691     CMIDTicker* ticker = new(ELeave) CMIDTicker;
       
   692     CleanupStack::PushL(TCleanupItem(CleanupTicker, ticker));
       
   693     ticker->ConstructL(aText);
       
   694     CleanupStack::Pop();
       
   695     return ticker;
       
   696 }
       
   697 
       
   698 // ---------------------------------------------------------------------------
       
   699 //
       
   700 // ---------------------------------------------------------------------------
       
   701 //
       
   702 CMIDTicker::CMIDTicker() :
       
   703         iRefCount(1)
       
   704 {
       
   705 }
       
   706 
       
   707 // ---------------------------------------------------------------------------
       
   708 //
       
   709 // ---------------------------------------------------------------------------
       
   710 //
       
   711 CMIDTicker::~CMIDTicker()
       
   712 {
       
   713     DEBUG("CMIDTicker::~CMIDTicker - calling StopL and RemoveDisplayableFromArrayL");
       
   714     TRAPD(ignore, StopL(); RemoveDisplayableFromArrayL(NULL));
       
   715     if (ignore != KErrNone)
       
   716     {
       
   717         DEBUG_INT("CMIDTicker::~CMIDTicker - Exception from StopL or RemoveDisplayableFromArrayL. Error = %d", ignore);
       
   718     }
       
   719     iDisplayableRArray.Reset();
       
   720     iDisplayableRArray.Close();
       
   721 
       
   722     delete iNaviDecorator;
       
   723     iNaviScrollingText = NULL; //deleted by navi decorator
       
   724 }
       
   725 
       
   726 // ---------------------------------------------------------------------------
       
   727 //
       
   728 // ---------------------------------------------------------------------------
       
   729 //
       
   730 void CMIDTicker::ConstructL(const TDesC& aText)
       
   731 {
       
   732     CAknNavigationControlContainer* naviC = NaviContainerL();
       
   733 
       
   734     iNaviScrollingText = CMIDScrollingText::NewL(this,aText);
       
   735     iNaviScrollingText->SetContainerWindowL(*naviC);
       
   736     iNaviScrollingText->SetExtent(TPoint(0,0), naviC->Size());
       
   737 
       
   738     iNaviDecorator = CAknNavigationDecorator::NewL(naviC, iNaviScrollingText, CAknNavigationDecorator::ENotSpecified);
       
   739     iNaviDecorator->SetContainerWindowL(*naviC);
       
   740     iNaviDecorator->MakeScrollButtonVisible(EFalse);
       
   741 }
       
   742 
       
   743 // ---------------------------------------------------------------------------
       
   744 //
       
   745 // ---------------------------------------------------------------------------
       
   746 //
       
   747 void CMIDTicker::Dispose()
       
   748 {
       
   749     if (iController)
       
   750     {
       
   751         TRAPD(ignore, iController->SetTickerL(NULL));
       
   752         if (ignore != KErrNone)
       
   753         {
       
   754             DEBUG_INT("CMIDTicker::Dispose - Exception from CMIDNaviPaneController::SetTickerL(NULL). Error = %d", ignore);
       
   755         }
       
   756     }
       
   757     delete this;
       
   758 }
       
   759 
       
   760 // ---------------------------------------------------------------------------
       
   761 //
       
   762 // ---------------------------------------------------------------------------
       
   763 //
       
   764 void CMIDTicker::SetTextL(const TDesC& aText)
       
   765 {
       
   766     iNaviScrollingText->SetTextL(aText);
       
   767 }
       
   768 
       
   769 void CMIDTicker::AddRef()
       
   770 {
       
   771     ++iRefCount;
       
   772 }
       
   773 
       
   774 // ---------------------------------------------------------------------------
       
   775 //
       
   776 // ---------------------------------------------------------------------------
       
   777 //
       
   778 void CMIDTicker::RemoveRef()
       
   779 {
       
   780     ASSERT(iRefCount);
       
   781     --iRefCount;
       
   782     if (0 == iRefCount)
       
   783     {
       
   784         delete this;
       
   785     }
       
   786 }
       
   787 
       
   788 // ---------------------------------------------------------------------------
       
   789 //
       
   790 // ---------------------------------------------------------------------------
       
   791 //
       
   792 void CMIDTicker::SetDisplayableL(CMIDDisplayable* aDisplayable, TInt aAdd)
       
   793 {
       
   794     ASSERT(aDisplayable);
       
   795 
       
   796     if (aAdd)
       
   797     { //KAddDisplayable:
       
   798         iDisplayableRArray.Append(aDisplayable);
       
   799     }
       
   800     else
       
   801     {
       
   802         RemoveDisplayableFromArrayL(aDisplayable);
       
   803     }
       
   804 }
       
   805 
       
   806 // ---------------------------------------------------------------------------
       
   807 // if aDisplayable is not null then remove it
       
   808 // if aDisplayable is NULL mean remove all
       
   809 // ---------------------------------------------------------------------------
       
   810 //
       
   811 void CMIDTicker::RemoveDisplayableFromArrayL(CMIDDisplayable* aDisplayable)
       
   812 {
       
   813     // if aDisplayable is not null then remove it.
       
   814     if (aDisplayable)
       
   815     {
       
   816         TInt index = iDisplayableRArray.Find(aDisplayable);
       
   817         if (index != KErrNotFound)
       
   818         {
       
   819             CMIDDisplayable* displayable = iDisplayableRArray[index];
       
   820             iDisplayableRArray.Remove(index);
       
   821             displayable->SetTickerL(NULL);
       
   822         }
       
   823     }
       
   824     else
       
   825     {// if aDisplayable is null mean remove all
       
   826         TInt count = iDisplayableRArray.Count();
       
   827         for (TInt ii = 0; ii<count; ii++)
       
   828         {
       
   829             // Always remove the Zeroth element as we are removing
       
   830             // the element array size is changing (reducing).
       
   831             CMIDDisplayable* displayable = iDisplayableRArray[0]; // index zero is required
       
   832             iDisplayableRArray.Remove(0);// index zero is required
       
   833             displayable->SetTickerL(NULL);
       
   834         }
       
   835     }
       
   836 }
       
   837 
       
   838 // ---------------------------------------------------------------------------
       
   839 // Start the ticker: we must disable any edit indicators (this is done by observers
       
   840 // but there is an observer, CDateFieldItem, which uses an editor (CEikMfne) which is not
       
   841 // FEP aware and hence cannot disable the edit indicators at the right time. So we have to
       
   842 // do it in here instead. The push the navi decorator on the navi pane. This will assure
       
   843 // our scrolling text will be drawn. */
       
   844 // ---------------------------------------------------------------------------
       
   845 //
       
   846 void CMIDTicker::StartL()
       
   847 {
       
   848     if (iNaviScrollingText->Size() == TSize(0,0))
       
   849     {
       
   850         iNaviScrollingText->SetExtent(TPoint(0,0), NaviContainerL()->Size());
       
   851         iNaviScrollingText->UpdateTickerLayoutL();
       
   852     }
       
   853 
       
   854     // to prevent panic if state indicator is NULL (it can happen when 3rd party FEP is active)
       
   855     MAknEditingStateIndicator* indicator = CAknEnv::Static()->EditingStateIndicator();
       
   856     if (indicator)
       
   857     {
       
   858         indicator->SetState(EStateNone);
       
   859     }
       
   860     NaviContainerL()->PushL(*iNaviDecorator);
       
   861     iNaviScrollingText->SetPaused(EFalse);
       
   862 }
       
   863 
       
   864 // ---------------------------------------------------------------------------
       
   865 // Pause the ticker, inform ScrollingText about pause mode, and remove our
       
   866 // navi decorator from the navi pane. */
       
   867 // ---------------------------------------------------------------------------
       
   868 //
       
   869 void CMIDTicker::PauseL()
       
   870 {
       
   871     iNaviScrollingText->SetPaused(ETrue);
       
   872     NaviContainerL()->Pop(iNaviDecorator);
       
   873 }
       
   874 
       
   875 
       
   876 // ---------------------------------------------------------------------------
       
   877 // Stop the ticker: just remove our navi decorator from the navi pane. */
       
   878 // ---------------------------------------------------------------------------
       
   879 //
       
   880 void CMIDTicker::StopL()
       
   881 {
       
   882     NaviContainerL()->Pop(iNaviDecorator);
       
   883     iNaviScrollingText->SetPaused(EFalse);
       
   884 }
       
   885 
       
   886 // ---------------------------------------------------------------------------
       
   887 // The text position is updated every tick, this achieves text scrolling. */
       
   888 // ---------------------------------------------------------------------------
       
   889 //
       
   890 void CMIDTicker::TickL(TInt aIncrement)
       
   891 {
       
   892     iNaviScrollingText->UpdateTextPositionL(aIncrement);
       
   893 }
       
   894 
       
   895 void CMIDTicker::SetController(CMIDNaviPaneController* aController)
       
   896 {
       
   897     iController = aController;
       
   898 }
       
   899 
       
   900 CMIDNaviPaneController* CMIDTicker::Controller() const
       
   901 {
       
   902     return iController;
       
   903 }
       
   904 
       
   905 void CMIDTicker::ReportEventL(CMIDNaviPaneController::TTickerEvent aEvent)
       
   906 {
       
   907     if (iController)
       
   908     {
       
   909         iController->TickerChangedL(this, aEvent);
       
   910     }
       
   911 }
       
   912 
       
   913 // ---------------------------------------------------------------------------
       
   914 // Relayout ScrollingText, cancel pause mode.
       
   915 // ---------------------------------------------------------------------------
       
   916 //
       
   917 void CMIDTicker::LayoutL()
       
   918 {
       
   919     iNaviScrollingText->SetPaused(EFalse);
       
   920     iNaviScrollingText->UpdateTickerLayoutL();
       
   921 }
       
   922 
       
   923 // ---------------------------------------------------------------------------
       
   924 // Redraw the status pane (out scrolling text is transparent so we need
       
   925 // the status pane to draw the navi pane background for us)
       
   926 // ---------------------------------------------------------------------------
       
   927 //
       
   928 void CMIDTicker::RenderL()
       
   929 {
       
   930     iAvkonAppUi->StatusPane()->DrawNow();
       
   931 }
       
   932 
       
   933 //
       
   934 // CMIDScrollingText
       
   935 //
       
   936 
       
   937 CMIDScrollingText* CMIDScrollingText::NewL(CMIDTicker* aParent, const TDesC& aText)
       
   938 {
       
   939     CMIDScrollingText* self = new(ELeave) CMIDScrollingText(aParent);
       
   940     CleanupStack::PushL(self);
       
   941     self->ConstructL(aText);
       
   942     CleanupStack::Pop(self);
       
   943     return self;
       
   944 }
       
   945 
       
   946 CMIDScrollingText::~CMIDScrollingText()
       
   947 {
       
   948     delete iPictographInterface;
       
   949     delete iText;
       
   950 }
       
   951 
       
   952 void CMIDScrollingText::UpdateTickerLayoutL()
       
   953 {
       
   954     const CFont* font = AknLayoutUtils::FontFromId(Layout().FontId());
       
   955     const CAknLayoutFont* layoutFont = CAknLayoutFont::AsCAknLayoutFontOrNull(font);
       
   956 
       
   957     if (layoutFont)
       
   958     {
       
   959         iBaseLineOffset = (iSize.iHeight - layoutFont->TextPaneHeight())/2 + layoutFont->TextPaneTopToBaseline();
       
   960     }
       
   961     else
       
   962     {
       
   963         iBaseLineOffset = (iSize.iHeight - font->HeightInPixels())/2 + font->AscentInPixels();
       
   964     }
       
   965 
       
   966     iTextWidth = font->TextWidthInPixels(iText->Text());
       
   967 
       
   968     if (!iPaused)
       
   969     {
       
   970         InitialiseScrollingTextPosition();
       
   971     }
       
   972 }
       
   973 
       
   974 void CMIDScrollingText::SetPaused(TBool aPause)
       
   975 {
       
   976     iPaused = aPause;
       
   977 }
       
   978 
       
   979 void CMIDScrollingText::SetTextL(const TDesC& aText)
       
   980 {
       
   981     HBufC* buf = aText.AllocL();
       
   982     CMIDUtils::MapJavaToETextChars(buf,EFalse);
       
   983     delete iText;
       
   984     iText = NULL;
       
   985     iText = TBidiText::NewL(buf->Des(),1);
       
   986 
       
   987     UpdateTickerLayoutL();
       
   988 }
       
   989 
       
   990 // ---------------------------------------------------------------------------
       
   991 // Static method returning an estimate of the scrolling width -
       
   992 // this must be the same for all tickers
       
   993 // ---------------------------------------------------------------------------
       
   994 //
       
   995 TInt CMIDScrollingText::ScrollingWidthL()
       
   996 {
       
   997     const CFont* font = AknLayoutUtils::FontFromId(Layout().FontId());
       
   998 
       
   999     TInt w = NaviContainerL()->Size().iWidth;
       
  1000     w -= (font->TextWidthInPixels(KLeftSquareBracket) + font->TextWidthInPixels(KRightSquareBracket));
       
  1001 
       
  1002     return w;
       
  1003 }
       
  1004 
       
  1005 CMIDScrollingText::CMIDScrollingText(CMIDTicker* aParent) : iParent(aParent)
       
  1006 {
       
  1007 }
       
  1008 
       
  1009 void CMIDScrollingText::ConstructL(const TDesC& aText)
       
  1010 {
       
  1011     SetTextL(aText);
       
  1012 
       
  1013     iPictographInterface = CAknPictographInterface::NewL(*this,*this);
       
  1014 }
       
  1015 
       
  1016 // ---------------------------------------------------------------------------
       
  1017 // Draw the text. Either "[ ... ]" or "(999) [ .. ]" where ... or .. is the
       
  1018 // scrolling text. Or if device is Right to Left: either "[ ... ]" or "[..] (999)" */
       
  1019 // ---------------------------------------------------------------------------
       
  1020 //
       
  1021 void CMIDScrollingText::Draw(const TRect& aRect) const
       
  1022 {
       
  1023     TAknTextLineLayout layout = Layout();
       
  1024 
       
  1025     CMIDNaviPaneController* controller = iParent->Controller();
       
  1026     const CFont* font = AknLayoutUtils::FontFromId(layout.FontId());
       
  1027     CWindowGc& gc = SystemGc();
       
  1028 
       
  1029     gc.SetPenColor(TextColor());
       
  1030     gc.UseFont(font);
       
  1031 
       
  1032 
       
  1033     //draw edit capacity text, eg "(999)" if needed
       
  1034     if (controller && controller->EditCapacityText() != NULL)
       
  1035     {
       
  1036         gc.DrawText(controller->EditCapacityText()->Text(), aRect, iBaseLineOffset, TextAlign(), 0);
       
  1037     }
       
  1038 
       
  1039     //draw "["
       
  1040     gc.DrawText(KLeftSquareBracket, TPoint(LeftTextPosition(font)
       
  1041                                            - font->TextWidthInPixels(KLeftSquareBracket),iBaseLineOffset));
       
  1042 
       
  1043     //draw "]"
       
  1044     gc.DrawText(KRightSquareBracket,TPoint(RightTextPosition(font),iBaseLineOffset));
       
  1045 
       
  1046 
       
  1047     //clip area for scrolling text
       
  1048     gc.SetClippingRect(TRect(TPoint(LeftTextPosition(font), 0), TPoint(RightTextPosition(font), iSize.iHeight)));
       
  1049 
       
  1050     //draw scrolling text
       
  1051     iText->WrapText(iTextWidth, *font,0);
       
  1052     if (iPictographInterface)
       
  1053     {
       
  1054         MAknPictographDrawer* aknPictographDrawer = iPictographInterface->Interface();
       
  1055         aknPictographDrawer->DrawText(gc, *font, iText->DisplayText(),
       
  1056                                       TPoint(iTextPosition,iBaseLineOffset));
       
  1057     }
       
  1058     else
       
  1059     {
       
  1060         iText->DrawText(gc, TPoint(iTextPosition,iBaseLineOffset));
       
  1061     }
       
  1062 
       
  1063     gc.CancelClippingRect();
       
  1064 }
       
  1065 
       
  1066 void CMIDScrollingText::HandleResourceChange(TInt aType)
       
  1067 {
       
  1068     CCoeControl::HandleResourceChange(aType);
       
  1069     if (aType==KEikDynamicLayoutVariantSwitch || aType == KEikColorResourceChange)
       
  1070     {
       
  1071         if (aType == KEikDynamicLayoutVariantSwitch && iParent && iParent->Controller())
       
  1072         {//change scrolling velocity if needed
       
  1073             DEBUG("CMIDScrollingText::HandleResourceChange - calling iParent->Controller()->ResetScrollingSpeedL");
       
  1074 
       
  1075             TRAPD(ignore, iParent->Controller()->ResetTickerScrollingSpeedL());
       
  1076             if (ignore != KErrNone)
       
  1077             {
       
  1078                 DEBUG_INT("CMIDScrollingText::HandleResourceChange - Exception from iParent->Controller()->ResetScrollingSpeedL. Error = %d", ignore);
       
  1079             }
       
  1080         }
       
  1081 
       
  1082         //reset position and layout
       
  1083         iPaused = false;
       
  1084         DEBUG("CMIDScrollingText::HandleResourceChange - calling UpdateTickerLayoutL");
       
  1085         TRAPD(ignore,UpdateTickerLayoutL());
       
  1086         if (ignore != KErrNone)
       
  1087         {
       
  1088             DEBUG_INT("CMIDScrollingText::HandleResourceChange - Exception from UpdateTickerLayoutL. Error = %d", ignore);
       
  1089         }
       
  1090 
       
  1091         //and finally draw
       
  1092         DrawNow();
       
  1093     }
       
  1094 }
       
  1095 
       
  1096 void CMIDScrollingText::SizeChanged()
       
  1097 {
       
  1098     // call parent implementation
       
  1099     CCoeControl::SizeChanged();
       
  1100 
       
  1101     // update layout
       
  1102     TRAP_IGNORE(UpdateTickerLayoutL());
       
  1103 }
       
  1104 
       
  1105 void CMIDScrollingText::DrawPictographArea()
       
  1106 {
       
  1107     // Does nothing - Ticker is updating himself
       
  1108 }
       
  1109 
       
  1110 // ---------------------------------------------------------------------------
       
  1111 // Scroll the text of aScrollAmount, the direction depends on the text directionality. The min
       
  1112 // and max text position are given by LeftTextPosition() and RightTextPosition().
       
  1113 // ---------------------------------------------------------------------------
       
  1114 //
       
  1115 void CMIDScrollingText::UpdateTextPositionL(TInt aScrollAmount)
       
  1116 {
       
  1117     const CFont* font = AknLayoutUtils::FontFromId(Layout().FontId());
       
  1118 
       
  1119     if (iPaused)
       
  1120     {
       
  1121         return;
       
  1122     }
       
  1123 
       
  1124     if (iText->Directionality() == TBidiText::ELeftToRight)
       
  1125     {
       
  1126         iTextPosition -= aScrollAmount;
       
  1127         if (iTextPosition < LeftTextPosition(font) - iTextWidth)
       
  1128         {
       
  1129             iTextPosition = RightTextPosition(font);
       
  1130         }
       
  1131     }
       
  1132     else
       
  1133     {
       
  1134         iTextPosition += aScrollAmount;
       
  1135         if (iTextPosition > RightTextPosition(font))
       
  1136         {
       
  1137             iTextPosition = LeftTextPosition(font) - iTextWidth;
       
  1138         }
       
  1139     }
       
  1140 
       
  1141     iParent->ReportEventL(CMIDNaviPaneController::EPositionChanged);
       
  1142 }
       
  1143 
       
  1144 
       
  1145 // ---------------------------------------------------------------------------
       
  1146 // The text color, this is taken from the layout + any skinning should be taken into account.
       
  1147 // ---------------------------------------------------------------------------
       
  1148 //
       
  1149 inline TRgb CMIDScrollingText::TextColor() const
       
  1150 {
       
  1151     TRgb color = AKN_LAF_COLOR(Layout().iC);
       
  1152 
       
  1153     MAknsSkinInstance* skin = AknsUtils::SkinInstance();
       
  1154     // Ignore error, color is not updated if it not found from the skin
       
  1155     AknsUtils::GetCachedColor(skin, color, KAknsIIDQsnTextColors, EAknsCIQsnTextColorsCG2);
       
  1156 
       
  1157     return color;
       
  1158 }
       
  1159 
       
  1160 // ---------------------------------------------------------------------------
       
  1161 // The space needed to draw "(999) " in pixels.
       
  1162 // ---------------------------------------------------------------------------
       
  1163 //
       
  1164 inline TInt CMIDScrollingText::EditCapacityWidth(const CFont* aFont) const
       
  1165 {
       
  1166     CMIDNaviPaneController* controller = iParent->Controller();
       
  1167 
       
  1168     if (controller && controller->EditCapacityText() != NULL)
       
  1169     {
       
  1170         return aFont->TextWidthInPixels(KTextCapacity);
       
  1171     }
       
  1172     return 0;
       
  1173 }
       
  1174 
       
  1175 // ---------------------------------------------------------------------------
       
  1176 // The left position for scrolling text. According to the device directionality
       
  1177 // we must add or not the edit capacity width.
       
  1178 // ---------------------------------------------------------------------------
       
  1179 //
       
  1180 inline TInt CMIDScrollingText::LeftTextPosition(const CFont* aFont) const
       
  1181 {
       
  1182     return aFont->TextWidthInPixels(KLeftSquareBracket) +
       
  1183            (TextAlign() == CGraphicsContext::ELeft ? EditCapacityWidth(aFont) : 0);
       
  1184 }
       
  1185 
       
  1186 // ---------------------------------------------------------------------------
       
  1187 // The right position for scrolling text. According to the device directionality
       
  1188 // must add or not the edit capacity width.
       
  1189 // ---------------------------------------------------------------------------
       
  1190 //
       
  1191 inline TInt CMIDScrollingText::RightTextPosition(const CFont* aFont) const
       
  1192 {
       
  1193     return iSize.iWidth - aFont->TextWidthInPixels(KRightSquareBracket) -
       
  1194            (TextAlign() == CGraphicsContext::ELeft ? 0 : EditCapacityWidth(aFont));
       
  1195 }
       
  1196 
       
  1197 // ---------------------------------------------------------------------------
       
  1198 // Sets the initial scrolling text position
       
  1199 // ---------------------------------------------------------------------------
       
  1200 //
       
  1201 void CMIDScrollingText::InitialiseScrollingTextPosition()
       
  1202 {
       
  1203     const CFont* font = AknLayoutUtils::FontFromId(Layout().FontId());
       
  1204     if (iText->Directionality() == TBidiText::ELeftToRight)
       
  1205     {
       
  1206         iTextPosition = RightTextPosition(font);
       
  1207     }
       
  1208     else
       
  1209     {
       
  1210         iTextPosition = LeftTextPosition(font) - iTextWidth;
       
  1211     }
       
  1212 }
       
  1213 
       
  1214 // End of File
       
  1215 
       
  1216 
       
  1217 
       
  1218 
       
  1219 
       
  1220 
       
  1221 
       
  1222 
       
  1223 
       
  1224 
       
  1225 
       
  1226 
       
  1227 
       
  1228 
       
  1229 
       
  1230 
       
  1231 
       
  1232 
       
  1233 
       
  1234 
       
  1235