diff -r f5050f1da672 -r 04becd199f91 javauis/lcdui_akn/lcdui/src/CMIDTicker.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/javauis/lcdui_akn/lcdui/src/CMIDTicker.cpp Tue Apr 27 16:30:29 2010 +0300 @@ -0,0 +1,1235 @@ +/* +* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Implementation of the Ticker component +* +*/ + + +#include +#include +#include +#include +// needed API for iAvkonAppUi +#include +#include +#include + +//#include +//#include +// CAknLayoutFont API for font layouting +#include + +#include +// CAknIndicatorContainer API for updating text capacity indicator +#include +// MAknEditingStateIndicator API for updating text capacity indicator +// and setting state to edit indicators +#include +#include +// CAknNavigationDecorator* iNaviDecorator +#include + +#include +#include +#include "CMIDTicker.h" +// needed for setting and removing displayables (iDisplayableRArray) +#include "CMIDDisplayable.h" +// CMIDUtils::MapJavaToETextChars in CMIDScrollingText::SetTextL +#include "CMIDUtils.h" +#include "CMIDUIManager.h" + +/** + * To enable ticker tracing, uncomment the follwing two lines and link + * to estlib.lib: + * + *#include + *#define TRACE_TICKER 1 + */ + +/** Time between each tick.*/ +const TInt KTickPeriod = 40000; + +/** Scrolling width in pixels where increment increases*/ +const TInt KScrollingWidthLimit = 200; + +/** Increment values for two different scrolling widths*/ +const TInt KOnePixel = 1; +const TInt KTwoPixels = 2; + +_LIT(KLeftSquareBracket, "["); +_LIT(KRightSquareBracket, "]"); +_LIT(KTextCapacity, "(999) "); + +_LIT(KLeftSmalllBracket, "("); +_LIT(KRightSmallBracket, ")"); + +#ifdef _DEBUG +#define DEBUG_ARG(x) x +#else +#define DEBUG_ARG(x) +#endif + +// +// Private helper functions +// +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +void CleanupTicker(TAny* aTicker) +{ + static_cast< CMIDTicker* >(aTicker)->Dispose(); +} + + +// --------------------------------------------------------------------------- +// Return the navi pane container. The method trapped should not leave. +// --------------------------------------------------------------------------- +// +CAknNavigationControlContainer* NaviContainerL() +{ + CEikStatusPane *sp = iAvkonAppUi->StatusPane(); + CAknNavigationControlContainer* naviC = + static_cast(sp->ControlL(TUid::Uid(EEikStatusPaneUidNavi))); + + return naviC; +} + +// --------------------------------------------------------------------------- +// Return a text layout defined in the platform LAF +// for text to be shown in the navi pane. According to the +// type of navi pane control the text layout may be different. +// We have chosen to use the same layout as the edit indicator +// text (the text showing how many chars are left in an editor). +// To use the layout used by navi pane labels use +// Navi_pane_texts_Line_1. This layout information determines the +// font and the text color. Text positioning is not taken from +// layout, the text is vertically centered and scrolled horizontally +// instead, h aligned to the left or right of the navi pane according +// to the directionality. +// --------------------------------------------------------------------------- +// +const TAknTextLineLayout Layout() +{ + return AknLayout::Small_status_pane_texts_Line_1(0); +} + +// --------------------------------------------------------------------------- +// Return the text alignment according to locale alignment +// --------------------------------------------------------------------------- +// +CGraphicsContext::TTextAlign TextAlign() +{ + return AknLayoutUtils::LayoutMirrored() ? CGraphicsContext::ERight : CGraphicsContext::ELeft; +} + +// +// class CMIDTickerController +// + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +CMIDNaviPaneController* CMIDNaviPaneController::NewL() +{ + CMIDNaviPaneController* self=new(ELeave) CMIDNaviPaneController(); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; +} + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +CMIDNaviPaneController::~CMIDNaviPaneController() +{ + delete iTickerTimer; + iTickerTimer = NULL; + delete iEditCapacityText; + iTickerObservers.Close(); +} + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +CMIDNaviPaneController::CMIDNaviPaneController() +{ +} + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +void CMIDNaviPaneController::ConstructL() +{ +} + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +void CMIDNaviPaneController::UpdateTextInputIndicatorL(TInt aCount) +{ + delete iEditCapacityText; + iEditCapacityText = NULL; + + if (aCount >= 0 && aCount <= 999) + { + const CFont* font = AknLayoutUtils::FontFromId(Layout().FontId()); + TBuf<10> text; + + text.Append(KLeftSmalllBracket); + text.AppendNum(aCount); + text.Append(KRightSmallBracket); + + // set text localized (non Latin numbers) + AknTextUtils::LanguageSpecificNumberConversion(text); + + iEditCapacityText = TBidiText::NewL(text,1); + iEditCapacityText->WrapText(font->TextWidthInPixels(KTextCapacity), *font, NULL); + + AddEditCapacityTextToNaviPaneL(); + } + else + { + // to prevent panic if state indicator is NULL (it can happen when 3rd party FEP is active) + MAknEditingStateIndicator* indicator = CAknEnv::Static()->EditingStateIndicator(); + if (indicator) + { + indicator->IndicatorContainer()->SetIndicatorState( + TUid::Uid(EAknNaviPaneEditorIndicatorMessageLength), + EAknIndicatorStateOff); + } + } +} + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +TBidiText* CMIDNaviPaneController::EditCapacityText() const +{ + return iEditCapacityText; +} + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +void CMIDNaviPaneController::AddTickerObserverL( + MMIDTickerObserver* aObserver) +{ + ASSERT(aObserver); + if (iTickerObservers.Find(aObserver) == KErrNotFound) + { + User::LeaveIfError(iTickerObservers.Append(aObserver)); + } +} + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +void CMIDNaviPaneController::RemoveTickerObserver( + MMIDTickerObserver* aObserver) +{ + ASSERT(aObserver); + TInt index = iTickerObservers.Find(aObserver); + if (index != KErrNotFound) + { + iTickerObservers.Remove(index); + } +} + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +void CMIDNaviPaneController::SetTickerL(CMIDTicker* aTicker) +{ + if (!iTickerTimer && !aTicker) + { + // CMIDTickerTimer instance is created only when + // a ticker object is set + return; + } + if (!iTickerTimer) + { + iTickerTimer = CMIDTickerTimer::NewL(this); + } + iTickerTimer->SetTickerL(aTicker); +} + + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +void CMIDNaviPaneController::ShowTickerL(TBool aShow) +{ + if (iTickerTimer) + { + iTickerTimer->ShowTickerL(aShow); + } +} + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +void CMIDNaviPaneController::PauseTickerL( + TInt aInterval, MMIDTickerObserver* aPausingObserver) +{ + if (aInterval > 0) + { + // Set last observer to pause the ticker + iPausingObserver = aPausingObserver; + } + if (iTickerTimer) + { + iTickerTimer->PauseTickerL(aInterval, aPausingObserver); + } +} + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +void CMIDNaviPaneController::TickerChangedL(CMIDTicker* aTicker, TTickerEvent aEvent) +{ + if (iTickerTimer) + { + iTickerTimer->TickerChangedL(aTicker, aEvent); + } +} + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +void CMIDNaviPaneController::LayoutTickerL() +{ + if (iTickerTimer) + { + iTickerTimer->LayoutTickerL(); + } +} + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +void CMIDNaviPaneController::ResetTickerScrollingSpeedL() +{ + if (iTickerTimer) + { + iTickerTimer->ResetScrollingSpeedL(); + } +} + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +void CMIDNaviPaneController::NotifyTickerObservers(TBool aShowing) +{ + TInt numObservers = iTickerObservers.Count(); + for (TInt index = 0; index < numObservers; index++) + { + iTickerObservers[ index ]->TickerShowing(aShowing); + } +} + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +void CMIDNaviPaneController::AddEditCapacityTextToNaviPaneL() +{ + if (iEditCapacityText != NULL && + (!iTickerTimer || + !iTickerTimer->iEnabled || + !iTickerTimer->iTicker)) + { + // to prevent panic if state indicator is NULL (it can happen when 3rd party FEP is active) + MAknEditingStateIndicator* indicator = CAknEnv::Static()->EditingStateIndicator(); + if (indicator) + { + indicator->IndicatorContainer()->SetIndicatorState( + TUid::Uid(EAknNaviPaneEditorIndicatorMessageLength), EAknIndicatorStateOn); + indicator->IndicatorContainer()->SetIndicatorValueL( + TUid::Uid(EAknNaviPaneEditorIndicatorMessageLength), iEditCapacityText->Text()); + } + } +} + + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +CMIDTickerTimer* CMIDTickerTimer::NewL(CMIDNaviPaneController* aController) +{ + CMIDTickerTimer* self=new(ELeave) CMIDTickerTimer(aController); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; +} + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +CMIDTickerTimer::~CMIDTickerTimer() +{ + DEBUG("CMIDTickerTimer::~CMIDTickerTimer - calling StopL"); + TRAPD(ignore,StopL()); + if (ignore != KErrNone) + { + DEBUG_INT("CMIDTickerTimer::~CMIDTickerTimer - Exception from StopL. Error = %d", ignore); + } +} + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +CMIDTickerTimer::CMIDTickerTimer(CMIDNaviPaneController* aCtrl) + : CTimer(CActive::EPriorityHigh) + , iCtrl(aCtrl) + , iTicker(NULL) + , iEnabled(EFalse) + , iIncrement(KOnePixel) +{ +} + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +void CMIDTickerTimer::ConstructL() +{ + CTimer::ConstructL(); + ResetScrollingSpeedL(); + CActiveScheduler::Add(this); +} + + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +void CMIDTickerTimer::RunL() +{ + if (iIsPaused) + { + iIsPaused = EFalse; + StartL(); + return; + } + + if (iTicker) + { + iTicker->TickL(iIncrement); + Kick(); + } +} + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +void CMIDTickerTimer::TickerChangedL( + CMIDTicker* aTicker, CMIDNaviPaneController::TTickerEvent aEvent) +{ + ASSERT(aTicker == iTicker); + (void)aTicker; // Just to suppress warning in release build + switch (aEvent) + { + case CMIDNaviPaneController::ENone: + case CMIDNaviPaneController::EModelChanged: + // ignore + break; + case CMIDNaviPaneController::ETextChanged: + break; + + case CMIDNaviPaneController::EPositionChanged: + iTicker->RenderL(); + break; + } +} + + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +void CMIDTickerTimer::ShowTickerL(TBool aShow) +{ + if (aShow) + { + StartL(); + } + else + { + StopL(); + } +} + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +void CMIDTickerTimer::SetTickerL(CMIDTicker* aTicker) +{ + if (iTicker != aTicker) + { + if (iTicker) + { + iTicker->StopL(); + iTicker->SetController(NULL); + iTicker->RemoveRef(); + } + + iTicker = aTicker; + + if (iTicker) + { + iTicker->AddRef(); + iTicker->SetController(iCtrl); + } + } + else + { + if (iTicker) + { + iTicker->PauseL(); + } + } + + // If the ticker is paused for textfield and textbox and displayable is changed + // cancel the pause timer and start the ticker + if (iIsPaused) + { + Cancel(); + } + + CheckedStart(); +} + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +void CMIDTickerTimer::PauseTickerL(TInt aInterval, MMIDTickerObserver* aPausingObserver) +{ + if (aInterval <= 0) + { + if (iCtrl->iPausingObserver == aPausingObserver) + { //only last requesting pausing observer can annulate request + iIsPaused = EFalse; + StartL(); + } + } + else + { + PauseL(); + After(aInterval); + iIsPaused = ETrue; + } +} + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +void CMIDTickerTimer::StartL() +{ + Cancel(); + + iEnabled = ETrue; + iCtrl->NotifyTickerObservers(iEnabled && iTicker); + + if (iTicker) + { + iTicker->StartL(); + } + + iCtrl->iPausingObserver = NULL; + iIsPaused = EFalse; + + CheckedStart(); +} + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +void CMIDTickerTimer::PauseL() +{ + Cancel(); + + iEnabled = EFalse; + iCtrl->NotifyTickerObservers(iEnabled); + + if (iTicker) + { + iTicker->PauseL(); + } + + iCtrl->AddEditCapacityTextToNaviPaneL(); +} + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +void CMIDTickerTimer::StopL() +{ + iEnabled = EFalse; + iCtrl->NotifyTickerObservers(iEnabled); + + if (iTicker) + { + iTicker->StopL(); + } + + iCtrl->AddEditCapacityTextToNaviPaneL(); + + Cancel(); +} + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +void CMIDTickerTimer::CheckedStart() +{ + if (!iEnabled) + { + return; + } + if (NULL == iTicker) + { + return; + } + + if (!IsActive()) + { + Kick(); + } +} + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +void CMIDTickerTimer::Kick() +{ + ASSERT(iEnabled); + ASSERT(iTicker); + if (!IsActive()) + { + After(KTickPeriod); + } +} + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +void CMIDTickerTimer::LayoutTickerL() +{ + ResetScrollingSpeedL(); + if (iTicker) + { + iTicker->LayoutL(); + } +} + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +void CMIDTickerTimer::ResetScrollingSpeedL() +{ + if (CMIDScrollingText::ScrollingWidthL() <= KScrollingWidthLimit) + { + iIncrement = KOnePixel; + } + else + { + iIncrement = KTwoPixels; + } +} + +// +// class CMIDTicker +// +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +MMIDTicker* CMIDTicker::NewL(const TDesC& aText) +{ + CMIDTicker* ticker = new(ELeave) CMIDTicker; + CleanupStack::PushL(TCleanupItem(CleanupTicker, ticker)); + ticker->ConstructL(aText); + CleanupStack::Pop(); + return ticker; +} + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +CMIDTicker::CMIDTicker() : + iRefCount(1) +{ +} + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +CMIDTicker::~CMIDTicker() +{ + DEBUG("CMIDTicker::~CMIDTicker - calling StopL and RemoveDisplayableFromArrayL"); + TRAPD(ignore, StopL(); RemoveDisplayableFromArrayL(NULL)); + if (ignore != KErrNone) + { + DEBUG_INT("CMIDTicker::~CMIDTicker - Exception from StopL or RemoveDisplayableFromArrayL. Error = %d", ignore); + } + iDisplayableRArray.Reset(); + iDisplayableRArray.Close(); + + delete iNaviDecorator; + iNaviScrollingText = NULL; //deleted by navi decorator +} + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +void CMIDTicker::ConstructL(const TDesC& aText) +{ + CAknNavigationControlContainer* naviC = NaviContainerL(); + + iNaviScrollingText = CMIDScrollingText::NewL(this,aText); + iNaviScrollingText->SetContainerWindowL(*naviC); + iNaviScrollingText->SetExtent(TPoint(0,0), naviC->Size()); + + iNaviDecorator = CAknNavigationDecorator::NewL(naviC, iNaviScrollingText, CAknNavigationDecorator::ENotSpecified); + iNaviDecorator->SetContainerWindowL(*naviC); + iNaviDecorator->MakeScrollButtonVisible(EFalse); +} + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +void CMIDTicker::Dispose() +{ + if (iController) + { + TRAPD(ignore, iController->SetTickerL(NULL)); + if (ignore != KErrNone) + { + DEBUG_INT("CMIDTicker::Dispose - Exception from CMIDNaviPaneController::SetTickerL(NULL). Error = %d", ignore); + } + } + delete this; +} + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +void CMIDTicker::SetTextL(const TDesC& aText) +{ + iNaviScrollingText->SetTextL(aText); +} + +void CMIDTicker::AddRef() +{ + ++iRefCount; +} + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +void CMIDTicker::RemoveRef() +{ + ASSERT(iRefCount); + --iRefCount; + if (0 == iRefCount) + { + delete this; + } +} + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +void CMIDTicker::SetDisplayableL(CMIDDisplayable* aDisplayable, TInt aAdd) +{ + ASSERT(aDisplayable); + + if (aAdd) + { //KAddDisplayable: + iDisplayableRArray.Append(aDisplayable); + } + else + { + RemoveDisplayableFromArrayL(aDisplayable); + } +} + +// --------------------------------------------------------------------------- +// if aDisplayable is not null then remove it +// if aDisplayable is NULL mean remove all +// --------------------------------------------------------------------------- +// +void CMIDTicker::RemoveDisplayableFromArrayL(CMIDDisplayable* aDisplayable) +{ + // if aDisplayable is not null then remove it. + if (aDisplayable) + { + TInt index = iDisplayableRArray.Find(aDisplayable); + if (index != KErrNotFound) + { + CMIDDisplayable* displayable = iDisplayableRArray[index]; + iDisplayableRArray.Remove(index); + displayable->SetTickerL(NULL); + } + } + else + {// if aDisplayable is null mean remove all + TInt count = iDisplayableRArray.Count(); + for (TInt ii = 0; iiSetTickerL(NULL); + } + } +} + +// --------------------------------------------------------------------------- +// Start the ticker: we must disable any edit indicators (this is done by observers +// but there is an observer, CDateFieldItem, which uses an editor (CEikMfne) which is not +// FEP aware and hence cannot disable the edit indicators at the right time. So we have to +// do it in here instead. The push the navi decorator on the navi pane. This will assure +// our scrolling text will be drawn. */ +// --------------------------------------------------------------------------- +// +void CMIDTicker::StartL() +{ + if (iNaviScrollingText->Size() == TSize(0,0)) + { + iNaviScrollingText->SetExtent(TPoint(0,0), NaviContainerL()->Size()); + iNaviScrollingText->UpdateTickerLayoutL(); + } + + // to prevent panic if state indicator is NULL (it can happen when 3rd party FEP is active) + MAknEditingStateIndicator* indicator = CAknEnv::Static()->EditingStateIndicator(); + if (indicator) + { + indicator->SetState(EStateNone); + } + NaviContainerL()->PushL(*iNaviDecorator); + iNaviScrollingText->SetPaused(EFalse); +} + +// --------------------------------------------------------------------------- +// Pause the ticker, inform ScrollingText about pause mode, and remove our +// navi decorator from the navi pane. */ +// --------------------------------------------------------------------------- +// +void CMIDTicker::PauseL() +{ + iNaviScrollingText->SetPaused(ETrue); + NaviContainerL()->Pop(iNaviDecorator); +} + + +// --------------------------------------------------------------------------- +// Stop the ticker: just remove our navi decorator from the navi pane. */ +// --------------------------------------------------------------------------- +// +void CMIDTicker::StopL() +{ + NaviContainerL()->Pop(iNaviDecorator); + iNaviScrollingText->SetPaused(EFalse); +} + +// --------------------------------------------------------------------------- +// The text position is updated every tick, this achieves text scrolling. */ +// --------------------------------------------------------------------------- +// +void CMIDTicker::TickL(TInt aIncrement) +{ + iNaviScrollingText->UpdateTextPositionL(aIncrement); +} + +void CMIDTicker::SetController(CMIDNaviPaneController* aController) +{ + iController = aController; +} + +CMIDNaviPaneController* CMIDTicker::Controller() const +{ + return iController; +} + +void CMIDTicker::ReportEventL(CMIDNaviPaneController::TTickerEvent aEvent) +{ + if (iController) + { + iController->TickerChangedL(this, aEvent); + } +} + +// --------------------------------------------------------------------------- +// Relayout ScrollingText, cancel pause mode. +// --------------------------------------------------------------------------- +// +void CMIDTicker::LayoutL() +{ + iNaviScrollingText->SetPaused(EFalse); + iNaviScrollingText->UpdateTickerLayoutL(); +} + +// --------------------------------------------------------------------------- +// Redraw the status pane (out scrolling text is transparent so we need +// the status pane to draw the navi pane background for us) +// --------------------------------------------------------------------------- +// +void CMIDTicker::RenderL() +{ + iAvkonAppUi->StatusPane()->DrawNow(); +} + +// +// CMIDScrollingText +// + +CMIDScrollingText* CMIDScrollingText::NewL(CMIDTicker* aParent, const TDesC& aText) +{ + CMIDScrollingText* self = new(ELeave) CMIDScrollingText(aParent); + CleanupStack::PushL(self); + self->ConstructL(aText); + CleanupStack::Pop(self); + return self; +} + +CMIDScrollingText::~CMIDScrollingText() +{ + delete iPictographInterface; + delete iText; +} + +void CMIDScrollingText::UpdateTickerLayoutL() +{ + const CFont* font = AknLayoutUtils::FontFromId(Layout().FontId()); + const CAknLayoutFont* layoutFont = CAknLayoutFont::AsCAknLayoutFontOrNull(font); + + if (layoutFont) + { + iBaseLineOffset = (iSize.iHeight - layoutFont->TextPaneHeight())/2 + layoutFont->TextPaneTopToBaseline(); + } + else + { + iBaseLineOffset = (iSize.iHeight - font->HeightInPixels())/2 + font->AscentInPixels(); + } + + iTextWidth = font->TextWidthInPixels(iText->Text()); + + if (!iPaused) + { + InitialiseScrollingTextPosition(); + } +} + +void CMIDScrollingText::SetPaused(TBool aPause) +{ + iPaused = aPause; +} + +void CMIDScrollingText::SetTextL(const TDesC& aText) +{ + HBufC* buf = aText.AllocL(); + CMIDUtils::MapJavaToETextChars(buf,EFalse); + delete iText; + iText = NULL; + iText = TBidiText::NewL(buf->Des(),1); + + UpdateTickerLayoutL(); +} + +// --------------------------------------------------------------------------- +// Static method returning an estimate of the scrolling width - +// this must be the same for all tickers +// --------------------------------------------------------------------------- +// +TInt CMIDScrollingText::ScrollingWidthL() +{ + const CFont* font = AknLayoutUtils::FontFromId(Layout().FontId()); + + TInt w = NaviContainerL()->Size().iWidth; + w -= (font->TextWidthInPixels(KLeftSquareBracket) + font->TextWidthInPixels(KRightSquareBracket)); + + return w; +} + +CMIDScrollingText::CMIDScrollingText(CMIDTicker* aParent) : iParent(aParent) +{ +} + +void CMIDScrollingText::ConstructL(const TDesC& aText) +{ + SetTextL(aText); + + iPictographInterface = CAknPictographInterface::NewL(*this,*this); +} + +// --------------------------------------------------------------------------- +// Draw the text. Either "[ ... ]" or "(999) [ .. ]" where ... or .. is the +// scrolling text. Or if device is Right to Left: either "[ ... ]" or "[..] (999)" */ +// --------------------------------------------------------------------------- +// +void CMIDScrollingText::Draw(const TRect& aRect) const +{ + TAknTextLineLayout layout = Layout(); + + CMIDNaviPaneController* controller = iParent->Controller(); + const CFont* font = AknLayoutUtils::FontFromId(layout.FontId()); + CWindowGc& gc = SystemGc(); + + gc.SetPenColor(TextColor()); + gc.UseFont(font); + + + //draw edit capacity text, eg "(999)" if needed + if (controller && controller->EditCapacityText() != NULL) + { + gc.DrawText(controller->EditCapacityText()->Text(), aRect, iBaseLineOffset, TextAlign(), 0); + } + + //draw "[" + gc.DrawText(KLeftSquareBracket, TPoint(LeftTextPosition(font) + - font->TextWidthInPixels(KLeftSquareBracket),iBaseLineOffset)); + + //draw "]" + gc.DrawText(KRightSquareBracket,TPoint(RightTextPosition(font),iBaseLineOffset)); + + + //clip area for scrolling text + gc.SetClippingRect(TRect(TPoint(LeftTextPosition(font), 0), TPoint(RightTextPosition(font), iSize.iHeight))); + + //draw scrolling text + iText->WrapText(iTextWidth, *font,0); + if (iPictographInterface) + { + MAknPictographDrawer* aknPictographDrawer = iPictographInterface->Interface(); + aknPictographDrawer->DrawText(gc, *font, iText->DisplayText(), + TPoint(iTextPosition,iBaseLineOffset)); + } + else + { + iText->DrawText(gc, TPoint(iTextPosition,iBaseLineOffset)); + } + + gc.CancelClippingRect(); +} + +void CMIDScrollingText::HandleResourceChange(TInt aType) +{ + CCoeControl::HandleResourceChange(aType); + if (aType==KEikDynamicLayoutVariantSwitch || aType == KEikColorResourceChange) + { + if (aType == KEikDynamicLayoutVariantSwitch && iParent && iParent->Controller()) + {//change scrolling velocity if needed + DEBUG("CMIDScrollingText::HandleResourceChange - calling iParent->Controller()->ResetScrollingSpeedL"); + + TRAPD(ignore, iParent->Controller()->ResetTickerScrollingSpeedL()); + if (ignore != KErrNone) + { + DEBUG_INT("CMIDScrollingText::HandleResourceChange - Exception from iParent->Controller()->ResetScrollingSpeedL. Error = %d", ignore); + } + } + + //reset position and layout + iPaused = false; + DEBUG("CMIDScrollingText::HandleResourceChange - calling UpdateTickerLayoutL"); + TRAPD(ignore,UpdateTickerLayoutL()); + if (ignore != KErrNone) + { + DEBUG_INT("CMIDScrollingText::HandleResourceChange - Exception from UpdateTickerLayoutL. Error = %d", ignore); + } + + //and finally draw + DrawNow(); + } +} + +void CMIDScrollingText::SizeChanged() +{ + // call parent implementation + CCoeControl::SizeChanged(); + + // update layout + TRAP_IGNORE(UpdateTickerLayoutL()); +} + +void CMIDScrollingText::DrawPictographArea() +{ + // Does nothing - Ticker is updating himself +} + +// --------------------------------------------------------------------------- +// Scroll the text of aScrollAmount, the direction depends on the text directionality. The min +// and max text position are given by LeftTextPosition() and RightTextPosition(). +// --------------------------------------------------------------------------- +// +void CMIDScrollingText::UpdateTextPositionL(TInt aScrollAmount) +{ + const CFont* font = AknLayoutUtils::FontFromId(Layout().FontId()); + + if (iPaused) + { + return; + } + + if (iText->Directionality() == TBidiText::ELeftToRight) + { + iTextPosition -= aScrollAmount; + if (iTextPosition < LeftTextPosition(font) - iTextWidth) + { + iTextPosition = RightTextPosition(font); + } + } + else + { + iTextPosition += aScrollAmount; + if (iTextPosition > RightTextPosition(font)) + { + iTextPosition = LeftTextPosition(font) - iTextWidth; + } + } + + iParent->ReportEventL(CMIDNaviPaneController::EPositionChanged); +} + + +// --------------------------------------------------------------------------- +// The text color, this is taken from the layout + any skinning should be taken into account. +// --------------------------------------------------------------------------- +// +inline TRgb CMIDScrollingText::TextColor() const +{ + TRgb color = AKN_LAF_COLOR(Layout().iC); + + MAknsSkinInstance* skin = AknsUtils::SkinInstance(); + // Ignore error, color is not updated if it not found from the skin + AknsUtils::GetCachedColor(skin, color, KAknsIIDQsnTextColors, EAknsCIQsnTextColorsCG2); + + return color; +} + +// --------------------------------------------------------------------------- +// The space needed to draw "(999) " in pixels. +// --------------------------------------------------------------------------- +// +inline TInt CMIDScrollingText::EditCapacityWidth(const CFont* aFont) const +{ + CMIDNaviPaneController* controller = iParent->Controller(); + + if (controller && controller->EditCapacityText() != NULL) + { + return aFont->TextWidthInPixels(KTextCapacity); + } + return 0; +} + +// --------------------------------------------------------------------------- +// The left position for scrolling text. According to the device directionality +// we must add or not the edit capacity width. +// --------------------------------------------------------------------------- +// +inline TInt CMIDScrollingText::LeftTextPosition(const CFont* aFont) const +{ + return aFont->TextWidthInPixels(KLeftSquareBracket) + + (TextAlign() == CGraphicsContext::ELeft ? EditCapacityWidth(aFont) : 0); +} + +// --------------------------------------------------------------------------- +// The right position for scrolling text. According to the device directionality +// must add or not the edit capacity width. +// --------------------------------------------------------------------------- +// +inline TInt CMIDScrollingText::RightTextPosition(const CFont* aFont) const +{ + return iSize.iWidth - aFont->TextWidthInPixels(KRightSquareBracket) - + (TextAlign() == CGraphicsContext::ELeft ? 0 : EditCapacityWidth(aFont)); +} + +// --------------------------------------------------------------------------- +// Sets the initial scrolling text position +// --------------------------------------------------------------------------- +// +void CMIDScrollingText::InitialiseScrollingTextPosition() +{ + const CFont* font = AknLayoutUtils::FontFromId(Layout().FontId()); + if (iText->Directionality() == TBidiText::ELeftToRight) + { + iTextPosition = RightTextPosition(font); + } + else + { + iTextPosition = LeftTextPosition(font) - iTextWidth; + } +} + +// End of File + + + + + + + + + + + + + + + + + + + + +