diff -r 000000000000 -r f72a12da539e idlehomescreen/xmluirendering/renderingplugins/xnnewstickerfactory/src/xnnewstickeradapter.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/idlehomescreen/xmluirendering/renderingplugins/xnnewstickerfactory/src/xnnewstickeradapter.cpp Thu Dec 17 08:40:49 2009 +0200 @@ -0,0 +1,1261 @@ +/* +* Copyright (c) 2002-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 for wrapper for a label +* +*/ + +// System includes +#include +#include +#include + +// User includes +#include "xnviewnodeimpl.h" +#include "xndompropertyvalue.h" +#include "xndomlist.h" +#include "xnproperty.h" +#include "xnnodepluginif.h" +#include "xntype.h" + +#include "c_xnutils.h" + +#include "xnnewstickeradapter.h" +#include "xnnewstickercontrol.h" +#include "xnnewstickersvgcontrol.h" +#include "xncomponentnodeimpl.h" + +// ============================= LOCAL FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// GetIntPropertyL +// Gets an integer property from the node. +// Returns: aNode UI node +// aproperty The property that is to be found +// return The value of the property. If not found, KErrNotFound returned. +// ----------------------------------------------------------------------------- +// +static TInt GetIntPropertyL( + CXnNodePluginIf& aNode, + const TDesC8& aProperty) + { + CXnProperty* prop = aNode.GetPropertyL(aProperty); + if(prop) + { + CXnDomPropertyValue* value = + static_cast(prop->Property()->PropertyValueList().Item(0)); + if(CXnDomPropertyValue::ENumber == value->PrimitiveValueType()) + { + TInt integer = static_cast(prop->FloatValueL()); + return integer; + } + } + return KErrNotFound; + } + +// ----------------------------------------------------------------------------- +// CopyBitmapData +// Copies a data from source bitmap to target bitmap. +// ----------------------------------------------------------------------------- +// +static TInt CopyBitmapData( + CFbsBitmap& aTarget, + const CFbsBitmap& aSource, + TPoint aSourcePoint) + { + TSize targetSize(aTarget.SizeInPixels()); + TSize sourceSize(aSource.SizeInPixels()); + TInt lineLength(targetSize.iWidth); + TInt maxSourceLineLength(sourceSize.iWidth - aSourcePoint.iX); + if(lineLength > maxSourceLineLength) + { + lineLength = maxSourceLineLength; + } + TInt rowCount(targetSize.iHeight); + TInt maxSourceRowCount(sourceSize.iHeight - aSourcePoint.iY); + if(rowCount > maxSourceRowCount) + { + rowCount = maxSourceRowCount; + } + + // Get bitmap display mode + TDisplayMode displayMode(aSource.DisplayMode()); + + // Create buffer for a scan line + HBufC8* scanLine = HBufC8::New( + aSource.ScanLineLength(lineLength, displayMode)); + if(!scanLine) + { + return KErrNoMemory; + } + + TPtr8 scanPtr(scanLine->Des()); + + // Copy all rows to destination bitmap + for(TInt row(0); row < rowCount; row++) + { + aSource.GetScanLine(scanPtr, + TPoint(aSourcePoint.iX, aSourcePoint.iY + row), + lineLength, displayMode); + aTarget.SetScanLine(scanPtr, row); + } + delete scanLine; + return KErrNone; + } + +// --------------------------------------------------------- +// CXnNewstickerAdapter::CheckDisplayL +// --------------------------------------------------------- +// +TBool CXnNewstickerAdapter::CheckDisplayL( CXnNodePluginIf& aNode ) + { + if( iPowerSaveMode ) + { + iDisplay = EFalse; + + return iDisplay; + } + + CXnProperty* displayProp( aNode.DisplayL() ); + + if( displayProp ) + { + const TDesC8& display( displayProp->StringValue() ); + + if( display != XnPropertyNames::style::common::display::KBlock ) + { + return EFalse; + } + } + + CXnProperty* visibilityProp( aNode.VisibilityL()); + + if( visibilityProp ) + { + const TDesC8& visibility( visibilityProp->StringValue() ); + + if( visibility != XnPropertyNames::style::common::visibility::KVisible ) + { + return EFalse; + } + } + + + CXnNodePluginIf* parent( aNode.ParentL() ); + + TBool ret( ETrue ); + + if( parent ) + { + ret = CheckDisplayL( *parent ); + } + + iDisplay = ret; + + return iDisplay; + } + +// --------------------------------------------------------- +// CXnNewstickerAdapter::SetNewstickerPropertiesL +// --------------------------------------------------------- +// +void CXnNewstickerAdapter::SetNewstickerPropertiesL() + { + // scroll amount + TInt scrollamount = GetIntPropertyL( iNode, + XnPropertyNames::newsticker::KXnScrollAmount ); // px + + if( KErrNotFound == scrollamount ) + { + scrollamount = KXnNewstickerScrollAmount; + } + + CXnProperty* prop( iNode.GetPropertyL( XnPropertyNames::newsticker::KScrollBehaviour ) ); + + if( prop ) + { + if ( prop->StringValue() == XnPropertyNames::newsticker::scroll_behaviour::KAlternate ) + { + scrollamount = 0; + iScrollBehaviour = EAlternate; + } + else if ( prop->StringValue() == XnPropertyNames::newsticker::scroll_behaviour::KSlide ) + { + iScrollBehaviour = ESlide; + } + else if ( prop->StringValue() == XnPropertyNames::newsticker::scroll_behaviour::KScrollAlternate ) + { + iScrollBehaviour = EScrollAlternate; + } + else + { + iScrollBehaviour = EScroll; + } + } + else + { + iScrollBehaviour = EScroll; + } + + iControl->SetScrollAmount( scrollamount ); + + if( iScrollBehaviour == EScroll || iScrollBehaviour == ESlide ) + { + // scroll delay + TInt scrolldelay = GetIntPropertyL( iNode, + XnPropertyNames::newsticker::KXnScrollDelay ); // ms + + if( KErrNotFound == scrolldelay ) + { + scrolldelay = KXnNewstickerInterval; + } + else + { + scrolldelay *= 1000; // change to microseconds + } + + iInterval = scrolldelay; + + // start delay + TInt startdelay = GetIntPropertyL( iNode, + XnPropertyNames::newsticker::KXnStartDelay ); // ms + + if( KErrNotFound == startdelay ) + { + startdelay = KXnNewstickerDelay; + } + else + { + startdelay *= 1000; // change to microseconds + } + + iDelay = startdelay; + } + else if( iScrollBehaviour == EScrollAlternate ) + { + // scroll delay + TInt scrolldelay = GetIntPropertyL( iNode, + XnPropertyNames::newsticker::KXnScrollDelay ); // ms + + if( KErrNotFound == scrolldelay ) + { + scrolldelay = KXnNewstickerInterval; + } + else + { + scrolldelay *= 1000; // change to microseconds + } + + iInterval = scrolldelay; + + TInt alternateTime( GetIntPropertyL( iNode, XnPropertyNames::newsticker::KDisplayTime ) ); + + if( alternateTime == KErrNotFound ) + { + alternateTime = 0; + } + + alternateTime *= 1000; // change to ms + + iAlternateInterval = alternateTime; + + // start delay + TInt startdelay = GetIntPropertyL( iNode, + XnPropertyNames::newsticker::KXnStartDelay ); // ms + + if( KErrNotFound == startdelay ) + { + startdelay = 0; + } + else + { + startdelay *= 1000; // change to microseconds + } + + iDelay = startdelay; + } + else // TScrollBehaviour::EAlternate + { + TInt alternateTime( GetIntPropertyL( iNode, XnPropertyNames::newsticker::KDisplayTime ) ); + + if( alternateTime == KErrNotFound ) + { + alternateTime = 0; + } + + alternateTime *= 1000; // change to ms + + iDelay = 0; + iInterval = alternateTime; + } + + // animation time + iAnimationTime = GetIntPropertyL( iNode, + XnPropertyNames::newsticker::KXnNewstickerAnimationDelay ); // ms + + if( KErrNotFound == iAnimationTime ) + { + iAnimationTime = KAnimationTime; + } + else + { + iAnimationTime *= 1000; // change to microseconds + } + + // _s60-scroll-loop property. True by default. + CXnProperty* loopProp( iNode.GetPropertyL( XnPropertyNames::newsticker::KScrollLoop ) ); + + if( loopProp && loopProp->StringValue() == XnPropertyNames::KFalse ) + { + iControl->SetScrollLooping( EFalse ); + } + else + { + iControl->SetScrollLooping( ETrue ); + } + CXnProperty* restartProperty( iNode.GetPropertyL( XnPropertyNames::newsticker::KRestartAfterUpdate ) ); + if ( restartProperty && restartProperty->StringValue() == XnPropertyNames::KTrue ) + { + iRestartAfterUpdate = ETrue; + } + } + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CXnNewstickerAdapter::NewL +// Symbian static 1st phase constructor +// ----------------------------------------------------------------------------- +// +CXnNewstickerAdapter* CXnNewstickerAdapter::NewL(CXnControlAdapter* aParent, + CXnNodePluginIf& aNode) + { + CXnNewstickerAdapter* self = new( ELeave ) CXnNewstickerAdapter( aParent, aNode ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop(); + return self; + } + +// ----------------------------------------------------------------------------- +// CXnNewstickerAdapter::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CXnNewstickerAdapter::ConstructL() + { + CXnControlAdapter::ConstructL( iNode ); + + iControl = CXnNewstickerControl::NewL( this ); + iSvgControl = CXnNewstickerSvgControl::NewL( this ); + + iPeriodicTimer = CPeriodic::NewL( CActive::EPriorityStandard ); + + iPowerSaveMode = ETrue; + + iRestartAfterUpdate = EFalse; + SetTextPropertiesL(); + SetNewstickerPropertiesL(); + + RPointerArray children = iNode.ChildrenL(); + CleanupClosePushL( children ); + for( TInt i = 0; i < children.Count(); ++i ) + { + CXnNodePluginIf* child( children[i] ); + + CXnType* xnType = child->Type(); + // We only care for nodes + if ( xnType && xnType->Type() == XnPropertyNames::title::KTitle ) + { + // Append title, if one is given from the theme use that. + // If no content yet available create empty title so that + // indexing is always current + const TDesC8& pcData( child->GetPCData() ); + + HBufC* pcData16 = CnvUtfConverter::ConvertToUnicodeFromUtf8L( pcData ); + CleanupStack::PushL( pcData16 ); + + TPtr ptr( pcData16->Des() ); + + CXnUtils::CollapseWhiteSpace( iNode, ptr ); + + if( ptr.Length() > 0 ) + { + iControl->AppendTitleL( *pcData16 ); + } + else + { + iControl->AppendTitleL( KNullDesC ); + } + + CleanupStack::PopAndDestroy( pcData16 ); + } + } + CleanupStack::PopAndDestroy( &children ); + } + +// ----------------------------------------------------------------------------- +// CXnNewstickerAdapter::CXnNewstickerAdapter +// C++ default constructor +// ----------------------------------------------------------------------------- +// +CXnNewstickerAdapter::CXnNewstickerAdapter(CXnControlAdapter* /*aParent*/, + CXnNodePluginIf& aNode) + : iState(ENotStarted), iNode(aNode) + { + } + +// ----------------------------------------------------------------------------- +// CXnNewstickerAdapter::~CXnNewstickerAdapter +// C++ destructor +// ----------------------------------------------------------------------------- +// +CXnNewstickerAdapter::~CXnNewstickerAdapter() + { + if( iPeriodicTimer ) + { + iPeriodicTimer->Cancel(); + } + + delete iPeriodicTimer; + + if( iFont && iReleaseFont ) + { + CWsScreenDevice* dev = iCoeEnv->ScreenDevice(); + dev->ReleaseFont( iFont ); + } + + delete iControl; + + if( iState == EAnimation ) + { + TRAP_IGNORE( iSvgControl->StopL() ); + } + + delete iSvgControl; + delete iBufferDevice; + delete iDrawingBuffer; + delete iBufferGc; + delete iBackgroundBitmap; + } + +// ----------------------------------------------------------------------------- +// CXnNewstickerAdapter::SetTextPropertiesL +// Sets text properties, such as color, font, etc. +// ----------------------------------------------------------------------------- +// +void CXnNewstickerAdapter::SetTextPropertiesL() + { + if (iFont && iReleaseFont) + { + CWsScreenDevice* dev = iCoeEnv->ScreenDevice(); + dev->ReleaseFont(iFont); + iFont = NULL; + } + CXnUtils::CreateFontL(iNode, iFont, iReleaseFont); + iControl->SetFont(iFont); + + TBool colorSet(EFalse); + CXnProperty* colorProperty = iNode.GetPropertyL(XnPropertyNames::appearance::common::KColor); + if (colorProperty != NULL) + { + CXnDomProperty* domProperty = colorProperty->Property(); + if(domProperty) + { + TRgb textColor; + TInt error( KErrNotSupported ); + CXnDomPropertyValue* value = static_cast< CXnDomPropertyValue* > + ( domProperty->PropertyValueList().Item( 0 ) ); + if( value->IsAutoIdent() ) + { + MAknsSkinInstance* skinInstance = AknsUtils::SkinInstance(); + error = AknsUtils::GetCachedColor(skinInstance, textColor, KAknsIIDQsnTextColors, + EAknsCIQsnTextColorsCG6); + } + else if( value->PrimitiveValueType() == CXnDomPropertyValue::ERgbColor ) + { + textColor = value->RgbColorValueL(); + error = KErrNone; + } + else + { + HBufC* colorString = colorProperty->StringValueL(); + CleanupStack::PushL( colorString ); + + CXnUtils::StripQuotes( colorString ); + + TInt index = 0; + TAknsItemID skinID; + + TBool idResolved = CXnUtils::ResolveSkinItemIDL( colorString->Des(), skinID, index ); + + if( idResolved ) + { + MAknsSkinInstance* skinInstance = AknsUtils::SkinInstance(); + error = AknsUtils::GetCachedColor( skinInstance, textColor, skinID, index ); + } + else // use auto value if skin id is invalid. + { + MAknsSkinInstance* skinInstance = AknsUtils::SkinInstance(); + error = AknsUtils::GetCachedColor(skinInstance, textColor, KAknsIIDQsnTextColors, + EAknsCIQsnTextColorsCG6); + } + CleanupStack::PopAndDestroy( colorString ); + } + if (error == KErrNone) + { + iControl->SetTextColor(textColor); + colorSet = ETrue; + } + } + } + + if(!colorSet) // Use text skin color + { + MAknsSkinInstance* skinInstance = AknsUtils::SkinInstance(); + TRgb textColor; + TInt error = AknsUtils::GetCachedColor( skinInstance, textColor, + KAknsIIDQsnTextColors, EAknsCIQsnTextColorsCG6); + if (error == KErrNone) + { + iControl->SetTextColor(textColor); + } + } + + CXnProperty* textDecorationProp = + iNode.GetPropertyL(XnPropertyNames::appearance::common::KTextDecoration); + if(textDecorationProp) + { + CXnDomList& propertyValueList = textDecorationProp->Property()->PropertyValueList(); + TInt valueCount = propertyValueList.Length(); + for (TInt i = 0; i < valueCount; ++i) + { + CXnDomPropertyValue* value = + static_cast<CXnDomPropertyValue*>(propertyValueList.Item(i)); + if (value->StringValueL() == + XnPropertyNames::appearance::common::textdecoration::KUnderline) + { + iControl->SetTextUnderlineStyle(EUnderlineOn); + } + if (value->StringValueL() == + XnPropertyNames::appearance::common::textdecoration::KLinethrough) + { + iControl->SetTextStrikethroughStyle(EStrikethroughOn); + } + } + } + + TGulAlignmentValue alignment = CXnUtils::TextAlignment( iNode ); + + TInt textAlignment( ELayoutAlignLeft ); // all are vertically top aligned by default (avkon) + + switch( alignment ) + { + case EHCenterVCenter: + textAlignment = ELayoutAlignCenter; + break; + case EHRightVCenter: + textAlignment = ELayoutAlignRight; + break; + default: + break; + } + + iControl->SetTextAlignment(textAlignment); + } + +// --------------------------------------------------------- +// CXnNewstickerAdapter::AppendTitleL +// --------------------------------------------------------- +// +void CXnNewstickerAdapter::AppendTitleL(const TDesC& aTitle) + { + iControl->AppendTitleL(aTitle); + iNode.SetDirtyL(); + } + +// --------------------------------------------------------- +// CXnNewstickerAdapter::InsertTitleL +// --------------------------------------------------------- +// +void CXnNewstickerAdapter::InsertTitleL(const TDesC& aTitle, TInt aIndex) + { + iControl->InsertTitleL(aTitle, aIndex); + iNode.SetDirtyL(); + } + +// --------------------------------------------------------- +// CXnNewstickerAdapter::UpdateTitleL +// --------------------------------------------------------- +// +void CXnNewstickerAdapter::UpdateTitleL(const TDesC& aTitle, TInt aIndex) + { + iControl->UpdateTitleL(aTitle, aIndex); + iNode.SetDirtyL(); + if ( iRestartAfterUpdate ) + { + RestartL(); + } + } + +// --------------------------------------------------------- +// CXnNewstickerAdapter::DeleteTitleL +// --------------------------------------------------------- +// +void CXnNewstickerAdapter::DeleteTitleL(TInt aIndex) + { + if( iState == EAnimation && iControl->CurrentTitleIndex() == aIndex ) + { + // About to delete the currently showing animation + iSvgControl->StopL(); + iControl->DeleteTitleL( aIndex ); + + RestartL(); + } + else + { + iControl->DeleteTitleL(aIndex); + } + + iNode.SetDirtyL(); + } + +// --------------------------------------------------------- +// CXnNewstickerAdapter::CurrentTitleIndex +// --------------------------------------------------------- +// +TInt CXnNewstickerAdapter::CurrentTitleIndex() + { + return iControl->CurrentTitleIndex(); + } + +// --------------------------------------------------------- +// CXnNewstickerAdapter::Title +// --------------------------------------------------------- +// +const TDesC& CXnNewstickerAdapter::Title(TInt aIndex) + { + return iControl->Title(aIndex); + } + +// --------------------------------------------------------- +// CXnNewstickerAdapter::SetSeparatorImageL +// --------------------------------------------------------- +// +TInt CXnNewstickerAdapter::SetSeparatorImageL(CGulIcon* aIcon) + { + return iControl->SetSeparatorImageL(aIcon); + } + +// --------------------------------------------------------- +// CXnNewstickerAdapter::ClearTitles +// --------------------------------------------------------- +// +void CXnNewstickerAdapter::ClearTitles() + { + iControl->ClearTitles(); + TRAP_IGNORE(iNode.SetDirtyL()); + } + +// --------------------------------------------------------- +// CXnNewstickerAdapter::AppendSvgTitleL +// --------------------------------------------------------- +// +void CXnNewstickerAdapter::AppendSvgTitleL(const TDesC8& aByteData) + { + iControl->AppendSvgTitleL(aByteData); + } + +// --------------------------------------------------------- +// CXnNewstickerAdapter::InsertSvgTitleL +// --------------------------------------------------------- +// +void CXnNewstickerAdapter::InsertSvgTitleL(const TDesC8& aByteData, TInt aIndex) + { + iControl->InsertSvgTitleL(aByteData, aIndex); + } + +// --------------------------------------------------------- +// CXnNewstickerAdapter::SetCallbackInterfaceL +// --------------------------------------------------------- +// +void CXnNewstickerAdapter::SetCallbackInterfaceL( + XnNewstickerInterface::MXnNewstickerCallbackInterface* aCallback) + { + iCallback = aCallback; + } + +// --------------------------------------------------------- +// CXnNewstickerAdapter::TitleScrolled +// --------------------------------------------------------- +// +void CXnNewstickerAdapter::TitleScrolled(TInt aTitleIndex) + { + if (iCallback) + { + iCallback->TitleScrolled(aTitleIndex); + } + // if not looping, see if the last item was scrolled... + if( !iControl->ScrollLooping() && + aTitleIndex == iControl->TitleCount() - 1 ) + { + iState = EScrollEnded; + TRAP_IGNORE( StopL() ); + DrawNow(); + } + } + +// ----------------------------------------------------------------------------- +// CXnNewstickerAdapter::DrawBackground() +// ----------------------------------------------------------------------------- +// +void CXnNewstickerAdapter::DrawBackgroundL(const TRect& aRect, CWindowGc& aGc) const + { + RPointerArray<CXnControlAdapter> adapters; + + for ( CXnNodePluginIf* node = &iNode; node; ) + { + CXnControlAdapter* adapter( node->Control() ); + + if ( adapter ) + { + adapters.Append( adapter ); + } + + node = node->ParentL(); + } + + for ( TInt i = adapters.Count() - 1; i >= 0; --i ) + { + adapters[i]->Draw( aRect, aGc ); + } + + adapters.Reset(); + } + +// ----------------------------------------------------------------------------- +// CXnNewstickerAdapter::SetTimerToDisplaytime() +// ----------------------------------------------------------------------------- +// +void CXnNewstickerAdapter::SetTimerToDisplaytime() + { + if( iCurrentInterval != iAlternateInterval ) + { + iPeriodicTimer->Cancel(); + + iPeriodicTimer->Start( + TTimeIntervalMicroSeconds32( iAlternateInterval ), + TTimeIntervalMicroSeconds32( iAlternateInterval ), + TCallBack( CXnNewstickerAdapter::PeriodicEventL, this ) ); + iCurrentInterval = iAlternateInterval; + } + } + +// ----------------------------------------------------------------------------- +// CXnNewstickerAdapter::SetTimerToScrolltime() +// ----------------------------------------------------------------------------- +// +void CXnNewstickerAdapter::SetTimerToScrolltime() + { + if( iCurrentInterval != iInterval ) + { + iPeriodicTimer->Cancel(); + + iPeriodicTimer->Start( + TTimeIntervalMicroSeconds32( iInterval ), + TTimeIntervalMicroSeconds32( iInterval ), + TCallBack( CXnNewstickerAdapter::PeriodicEventL, this ) ); + iCurrentInterval = iInterval; + } + } +// --------------------------------------------------------- +// CXnNewstickerAdapter::StartL +// --------------------------------------------------------- +// +void CXnNewstickerAdapter::StartL() + { + if( iDisplay && !iPowerSaveMode ) + { + if( iControl->TitleCount() == 0 ) + { + // Nothing to show + return; + } + + if( iPeriodicTimer && !iPeriodicTimer->IsActive() ) + { + TInt startDelay( ( iState == ENotStarted ) ? iDelay : KNoDelay ); + + // Start + if ( ScrollBehaviour() == CXnNewstickerAdapter::EScrollAlternate && + iControl->CalculateCurrentTextFitInNewstickerRect() ) + { + iPeriodicTimer->Start( + TTimeIntervalMicroSeconds32( startDelay ), + TTimeIntervalMicroSeconds32( iAlternateInterval ), + TCallBack( CXnNewstickerAdapter::PeriodicEventL, this ) ); + iCurrentInterval = iAlternateInterval; + } + else + { + iPeriodicTimer->Start( + TTimeIntervalMicroSeconds32( startDelay ), + TTimeIntervalMicroSeconds32( iInterval ), + TCallBack( CXnNewstickerAdapter::PeriodicEventL, this ) ); + iCurrentInterval = iInterval; + } + + iState = EText; + } + } + } + +// --------------------------------------------------------- +// CXnNewstickerAdapter::StopL +// --------------------------------------------------------- +// +void CXnNewstickerAdapter::StopL() + { + if( iState == EAnimation ) + { + iSvgControl->StopL(); + } + + // Have we already been started + if( iPeriodicTimer->IsActive() ) + { + // Yes, cancel and set the state + iPeriodicTimer->Cancel(); + + if ( iState == EScrollEnded ) + { + iControl->MoveToLastL(); + iControl->DrawStatic(); + } + else if ( iState == EText || iState == EAnimation ) + { + iState = EPaused; + } + } + // Entering power save mode => Move to last item and draw it + if ( ( iScrollBehaviour == EAlternate || + iScrollBehaviour == EScrollAlternate ) + && iPowerSaveMode ) + { + iState = EPaused; + iControl->MoveToLastL(); + iControl->DrawStatic(); + } + } + +// --------------------------------------------------------- +// CXnNewstickerAdapter::ShowSvgL +// --------------------------------------------------------- +// +void CXnNewstickerAdapter::ShowSvgL() + { + // Get next animation from model and start it + iSvgControl->StartL( iControl->CurrentSvgTitle() ); + + // Set the end timer + iState = EAnimation; + + iPeriodicTimer->Cancel(); + + iPeriodicTimer->Start( + TTimeIntervalMicroSeconds32( iAnimationTime ), + TTimeIntervalMicroSeconds32( iAnimationTime ), + TCallBack( CXnNewstickerAdapter::PeriodicEventL, this ) ); + iCurrentInterval = iAnimationTime; + } + +// --------------------------------------------------------- +// CXnNewstickerAdapter::PeriodicEventL +// --------------------------------------------------------- +// +TInt CXnNewstickerAdapter::PeriodicEventL( TAny* aPtr ) + { + CXnNewstickerAdapter* self = static_cast< CXnNewstickerAdapter* >( aPtr ); + + if( self->iState == EText ) + { + // Do the text scroll + self->iControl->DoScrollL(); + } + else if( self->iState == EAnimation ) + { + self->iSvgControl->StopL(); + self->TitleScrolled( self->iControl->CurrentTitleIndex() ); + // Animation scroll has been ended, start the next scroll + self->iState = ENotStarted; + self->iPeriodicTimer->Cancel(); + self->StartL(); + // Do the first draw + self->iControl->SetBeginningState(); + self->iControl->DoScrollL(); + } + + return KErrNone; + } + +void CXnNewstickerAdapter::RestartL() + { + if ( iPowerSaveMode ) + { + return; + } + // Restart + iState = ENotStarted; + iPeriodicTimer->Cancel(); + + iControl->MoveToFirstL(); + StartL(); + + // Do the first draw + iControl->SetBeginningState(); + } +// --------------------------------------------------------- +// CXnNewstickerAdapter::SizeChanged() +// --------------------------------------------------------- +// +void CXnNewstickerAdapter::SizeChanged() + { + CXnControlAdapter::SizeChanged(); + TRAP_IGNORE( SizeChangedL() ); + } + +// --------------------------------------------------------- +// CXnNewstickerAdapter::SizeChangedL() +// --------------------------------------------------------- +// +void CXnNewstickerAdapter::SizeChangedL() + { + UpdateDoubleBufferL(); + + TRect rect( Rect() ); + + iControl->SetNewstickerRect( rect ); + iSvgControl->SetSvgRectL( rect, *SystemGc().Device() ); + } + +// ----------------------------------------------------------------------------- +// CXnNewstickerAdapter::HandlePointerEventL +// ----------------------------------------------------------------------------- +// +void CXnNewstickerAdapter::HandlePointerEventL(const TPointerEvent& aPointerEvent) + { + if ( AknLayoutUtils::PenEnabled() ) + { + CXnControlAdapter::HandlePointerEventL(aPointerEvent); + } + } +// ----------------------------------------------------------------------------- +// CXnNewstickerAdapter::DoHandlePropertyChangeL +// ----------------------------------------------------------------------------- +// +void CXnNewstickerAdapter::DoHandlePropertyChangeL( CXnProperty* aProperty ) + { + SetTextPropertiesL(); + SetNewstickerPropertiesL(); + //New code to check do we need Start or Stop Newsticker + if( aProperty ) + { + const TDesC8& name( aProperty->Property()->Name() ); + + if( name == XnPropertyNames::style::common::KDisplay || + name == XnPropertyNames::style::common::KVisibility ) + { + if( CheckDisplayL( iNode ) ) + { + StartL(); + } + else + { + StopL(); + } + } + } + } + +// ----------------------------------------------------------------------------- +// CXnNewstickerAdapter::FocusChanged +// ----------------------------------------------------------------------------- +// +void CXnNewstickerAdapter::FocusChanged(TDrawNow /*aDrawNow*/) + { + } + +// ----------------------------------------------------------------------------- +// CXnNewstickerAdapter::SkinChanged +// ----------------------------------------------------------------------------- +// +void CXnNewstickerAdapter::SkinChanged() + { + CXnControlAdapter::SkinChanged(); + TRAP_IGNORE( SetTextPropertiesL() ); + } + +void CXnNewstickerAdapter::ReportNewstickerEventL(const TDesC8& aEventName) + { + TBuf8<8>index(KNullDesC8); + index.Num(CurrentTitleIndex()); + + iNode.ReportTriggerEventL(aEventName, + XnPropertyNames::action::trigger::name::KTitleIndex, index); + } +// ----------------------------------------------------------------------------- +// CXnNewstickerAdapter::OfferKeyEventL +// ----------------------------------------------------------------------------- +// +TKeyResponse CXnNewstickerAdapter::OfferKeyEventL( + const TKeyEvent& aKeyEvent, TEventCode aType) + { + TKeyResponse resp = EKeyWasNotConsumed; + TBool restart = EFalse; + + CXnControlAdapter::OfferKeyEventL(aKeyEvent, aType); + + if(aType == EEventKey) + { + if (aKeyEvent.iScanCode == EStdKeyRightArrow) + { + restart = ETrue; + if(iControl->IsWestern()) + { + iControl->MoveToNextL(); + } + else + { + iControl->MoveToPrevL(); + } + StopL(); + } + else if (aKeyEvent.iScanCode == EStdKeyLeftArrow) + { + restart = ETrue; + if(iControl->IsWestern()) + { + iControl->MoveToPrevL(); + } + else + { + iControl->MoveToNextL(); + } + StopL(); + } + } + if(aType == EEventKeyUp) + { + if (aKeyEvent.iScanCode == EStdKeyDevice3) // rocker + { + restart = ETrue; + StopL(); + iControl->MoveToCurrent(); + } + } + + if( restart ) + { + // Restart and do the first draw + iState = ENotStarted; + StartL(); + iControl->DoScrollL(); + } + + return resp; + } + +// ----------------------------------------------------------------------------- +// CXnNewstickerAdapter::Draw +// Draws the text component +// ----------------------------------------------------------------------------- +void CXnNewstickerAdapter::Draw(const TRect& aRect) const + { + CXnControlAdapter::Draw( aRect ); + + TRAP_IGNORE( UpdateBackgroundL() ); + // In powersave-/editmode only draw the last title. + if ( iScrollBehaviour == EAlternate && iPowerSaveMode ) + { + iControl->DrawStatic(); + + // Blit double buffer + SystemGc().BitBlt( Rect().iTl, iDrawingBuffer ); + } + else if( iState == EText || iState == EPaused && + iControl->CurrentTitleIndex() >= 0 ) + { + iControl->Draw(); + + // Blit double buffer + SystemGc().BitBlt( Rect().iTl, iDrawingBuffer ); + } + else if( iState == EAnimation ) + { + iSvgControl->Draw(); + + // Blit double buffer + SystemGc().BitBlt( Rect().iTl, iDrawingBuffer ); + } + else if( iState == EScrollEnded ) + { + iControl->DrawStatic(); + SystemGc().BitBlt( Rect().iTl, iDrawingBuffer ); + } + } + +// ----------------------------------------------------------------------------- +// CXnNewstickerAdapter::UpdateDoubleBufferL +// ----------------------------------------------------------------------------- +// +void CXnNewstickerAdapter::UpdateDoubleBufferL() + { + TDisplayMode displayMode( SystemGc().Device()->DisplayMode() ); + + // Create double buffer + if( iDrawingBuffer ) + { + delete iDrawingBuffer; + iDrawingBuffer = NULL; + delete iBufferDevice; + iBufferDevice = NULL; + delete iBufferGc; + iBufferGc = NULL; + } + + iDrawingBuffer = new ( ELeave ) CFbsBitmap(); + iDrawingBuffer->Create( iNode.Rect().Size(), displayMode ); + iBufferDevice = CFbsBitmapDevice::NewL( iDrawingBuffer ); + iBufferDevice->CreateBitmapContext( iBufferGc ); + iBufferGc->UseFont( iControl->Font() ); + iBufferGc->SetPenColor( iControl->TextColor() ); + iBufferGc->SetStrikethroughStyle( iControl->TextStrikethroughStyle() ); + iBufferGc->SetUnderlineStyle( iControl->TextUnderlineStyle() ); + } + +// ----------------------------------------------------------------------------- +// CXnNewstickerAdapter::UpdateBackgroundL +// ----------------------------------------------------------------------------- +// +void CXnNewstickerAdapter::UpdateBackgroundL() const + { + TDisplayMode displayMode( SystemGc().Device()->DisplayMode() ); + + // Create "screenshot" from the background appearance + if( iBackgroundBitmap ) + { + delete iBackgroundBitmap; + iBackgroundBitmap = NULL; + } + + iBackgroundBitmap = new ( ELeave ) CFbsBitmap(); + iBackgroundBitmap->Create( iNode.Rect().Size(), displayMode ); + + CFbsBitmap* tmpBitmap = new ( ELeave ) CFbsBitmap(); + CleanupStack::PushL( tmpBitmap ); + + CWsScreenDevice* scrDevice = static_cast< CWsScreenDevice* >( SystemGc().Device() ); + + TSize tmpSize( scrDevice->SizeInPixels() ); + + tmpBitmap->Create( tmpSize, displayMode ); + + CFbsBitmapDevice* tmpDevice = CFbsBitmapDevice::NewL( tmpBitmap ); + CleanupStack::PushL( tmpDevice ); + + CBitmapContext* bc( NULL ); + + tmpDevice->CreateBitmapContext( bc ); + CleanupStack::PushL( bc ); + + DrawBackgroundL( iNode.Rect(), reinterpret_cast< CWindowGc& >( *bc ) ); + + CopyBitmapData( *iBackgroundBitmap, *tmpBitmap, iNode.Rect().iTl ); + + CleanupStack::PopAndDestroy( 3 ); + } + +// ----------------------------------------------------------------------------- +// CXnNewstickerAdapter::DoEnterPowerSaveModeL +// Enter power save mode +// ----------------------------------------------------------------------------- +void CXnNewstickerAdapter::DoEnterPowerSaveModeL(TModeEvent /*aEvent*/) + { + iDisplay = EFalse; + iPowerSaveMode = ETrue; + + StopL(); + } + +// ----------------------------------------------------------------------------- +// CXnNewstickerAdapter::DoExitPowerSaveModeL +// Exit power save mode +// ----------------------------------------------------------------------------- +void CXnNewstickerAdapter::DoExitPowerSaveModeL(TModeEvent /*aEvent*/) + { + iPowerSaveMode = EFalse; + + if( CheckDisplayL( iNode ) ) + { + RestartL(); + + if( iDrawingBuffer ) + { + DrawNow(); + } + } + } + +// ----------------------------------------------------------------------------- +// CXnNewstickerAdapter::DrawNow +// Draw +// ----------------------------------------------------------------------------- +void CXnNewstickerAdapter::DrawNow() const + { + TBool parentDrawn = EFalse; + TRAP_IGNORE( parentDrawn = DrawFocusableParentL() ); + if ( !parentDrawn ) + { + CCoeControl::DrawNow(); + } + } + +// ----------------------------------------------------------------------------- +// CXnNewstickerAdapter::DrawFocusableParentL +// Draws focusable parent +// ----------------------------------------------------------------------------- +TBool CXnNewstickerAdapter::DrawFocusableParentL() const + { + TBool parentDrawn = EFalse; + + if ( !iNode.IsFocusedState() ) + { + // node is not focusable, find focusable and focused parent + CXnNodePluginIf* parent = iNode.ParentL(); + while ( parent && !parent->IsFocusedState() ) + { + parent = parent->ParentL(); + } + + if (parent) + { + // focusable parent found, draw it + parent->Control()->DrawNow(); + parentDrawn = ETrue; + } + } + + return parentDrawn; + } + +// End of file