menufw/menufwui/mmwidgets/src/mmmarqueeadapter.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Thu, 17 Dec 2009 08:40:49 +0200
changeset 0 f72a12da539e
permissions -rw-r--r--
Revision: 200949 Kit: 200951

/*
* Copyright (c) 2007 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:  
*
*/


#include <aknlayoutscalable_avkon.cdl.h>
#include <AknUtils.h>
#include <eikfrlb.h>
#include <AknBidiTextUtils.h>
#include <gdi.h>
#include <AknLayoutFont.h>

#include "mmlistbox.h"
#include "mmmarqueeadapter.h"
#include "mmwidgetsconstants.h"

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
// 
CMmMarqueeAdapter::CMmMarqueeAdapter ()
	{
	// No implementation required
	}

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
// 
CMmMarqueeAdapter::~CMmMarqueeAdapter ()
	{
	iMarqueeElements.ResetAndDestroy();
	}

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
// 
CMmMarqueeAdapter* CMmMarqueeAdapter::NewLC ()
	{
	CMmMarqueeAdapter* self = new (ELeave)CMmMarqueeAdapter();
	CleanupStack::PushL (self);
	self->ConstructL ();
	return self;
	}

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
// 
CMmMarqueeAdapter* CMmMarqueeAdapter::NewL ()
	{
	CMmMarqueeAdapter* self = CMmMarqueeAdapter::NewLC ();
	CleanupStack::Pop( self );
	return self;
	}

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
// 
void CMmMarqueeAdapter::ConstructL ()
	{
	iMarqueeEnabled = ETrue;
	iCurrentMarqueeItemIndex = -1;
	}

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
// 
void CMmMarqueeAdapter::AddMarqueeElementL(
	    const TRect& aRect,
	    const TDesC& aText,
	    TAknLogicalFontId aFont,
	    TRgb  aColor,
		CGraphicsContext::TTextAlign aAlign,
		TInt aIndex,
		TInt aBaselineOffset,
		TInt aCurrentlyDrawnItemIndex
	    )
	{
	if( !iMarqueeEnabled )
		{
		return;
		}
	
	if ( aCurrentlyDrawnItemIndex != iCurrentMarqueeItemIndex )
		{
		StopMarqueeDrawing();
		iCurrentMarqueeItemIndex = aCurrentlyDrawnItemIndex;
		}

	CMmMarqueeElement* element = NULL;
	TInt elementIndex(0);
	for (TInt i = 0; i < iMarqueeElements.Count() ; i++)
		{
		if (iMarqueeElements[i]->iSubcellIndex == aIndex)
			{
			element = iMarqueeElements[i];
			elementIndex = i;
			break;
			}
		}

	if ( element )
		{
		const TDesC& previousText = *(element->iText);
		TBool textChanged = previousText.Compare( aText );
	
		if ( textChanged )
			{
			CAknMarqueeControl * control = element->iMarqueeControl;
			control->Stop();
			control->Reset();
			iMarqueeElements.Remove(elementIndex );
			delete element;
			}
		}
	
	if( SubcellMarqueeElementExists( aIndex ) )
		{
		return;
		}
		
	CMmMarqueeElement* newElement = 
		CMmMarqueeElement::NewL( aRect, aAlign, aText, aFont, aColor, aIndex, aBaselineOffset );
	CleanupStack::PushL( newElement );
	newElement->SetupMarqueeControlL( MmMarqueeConstants::KLoops,
			MmMarqueeConstants::KScrollAmount, MmMarqueeConstants::KScrollDelay);
    TCallBack callBack(CMmMarqueeAdapter::RedrawEvent, iListbox);
    if ( newElement->iMarqueeControl ) 
    	{
        newElement->iMarqueeControl->SetRedrawCallBack(callBack);
    	}
    iMarqueeElements.AppendL( newElement );
    CleanupStack::Pop( newElement );
	}

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
// 
void CMmMarqueeAdapter::StopMarqueeDrawing(TInt aIndex)
	{
    for (TInt elementIndex = iMarqueeElements.Count() - 1;
            elementIndex >= 0; elementIndex--)
        {
        if ((aIndex < 0) ||
                (iMarqueeElements[elementIndex]->iSubcellIndex == aIndex))
            {
            CMmMarqueeElement* element = iMarqueeElements[elementIndex];
            CAknMarqueeControl * control = element->iMarqueeControl;
            control->Stop();
            control->Reset();
            iMarqueeElements.Remove(elementIndex);
            delete element;
            if (iMarqueeElements.Count() == 0 || (aIndex >= 0))
                {
                iCurrentMarqueeItemIndex = -1;
                break;
                }
            }
        }
    }

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
// 
void CMmMarqueeAdapter::EnableMarquee( TBool aEnable )
	{
	iMarqueeEnabled = aEnable;
	}

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
// 
void CMmMarqueeAdapter::DrawMarqueeL(CWindowGc & aGc )
	{
	if ( iCurrentMarqueeItemIndex != iListbox->View()->CurrentItemIndex() )
		{
		StopMarqueeDrawing();
		return;
		}
	else if ( iMarqueeEnabled )
		{
		for (TInt i = 0; i < iMarqueeElements.Count() ; i++)
			{
			CMmMarqueeElement* element = iMarqueeElements[i];
			CAknMarqueeControl* control = element->iMarqueeControl;
			control->EnableMarquee( ETrue );
			
//			Setup graphical context ( font, colors ) for marquee
			const CFont* font = AknLayoutUtils::FontFromId( element->iFont );
            TInt baseLineOffset = CAknLayoutFont::AsCAknLayoutFontOrNull( font )->TextPaneTopToBaseline();
            aGc.UseFont(font);
            aGc.SetPenColor( element->iColor );
            aGc.SetBrushStyle( CGraphicsContext::ENullBrush );
            
//			Let marquee know if it needs to do bidi conversion
            control->UseLogicalToVisualConversion( ETrue );
            
            TRect subcellRectOnScreen = element->iElementRect;
            TPoint currentItemPositionOnScreen 
				= iListbox->View()->ItemPos( iListbox->View()->CurrentItemIndex() );
            subcellRectOnScreen.Move( currentItemPositionOnScreen.iX , currentItemPositionOnScreen.iY );
            if ( control->DrawText(aGc, subcellRectOnScreen, *(element->iText),
            		baseLineOffset, element->iAlign, *font) )
            	
                {
//              All the loops have been executed, the text needs to be truncated.
                TBuf< MmMarqueeConstants::KClippingBufLength > clipbuf 
					= (element->iText)->Left( MmMarqueeConstants::KTextTrimmingThreshold );
//              Get the clipping buffer and draw it
            	TInt maxClipWidth = element->iElementRect.Width();
                AknBidiTextUtils::ConvertToVisualAndClipL( clipbuf, *font,
                		element->iElementRect.Width(), maxClipWidth );
                aGc.DrawText(clipbuf, subcellRectOnScreen, baseLineOffset , element->iAlign, 0);
                }
//          Clean the font cache in graphical context after marquee drawing
            aGc.DiscardFont();
			}
		}
	}

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
// 
TInt CMmMarqueeAdapter::RedrawEvent(TAny* aControl )
    {
    if ( !((CCoeControl*)aControl)->IsVisible() )
        {
        return EFalse;
        }
    
    CMmListBox* listBox = 
            (CMmListBox*)aControl;
    if (listBox->CurrentItemIndex() >= 0 
    		&& listBox->CurrentItemIndex() <= listBox->View()->BottomItemIndex()
    		&& listBox->CurrentItemIndex() >= listBox->View()->TopItemIndex()
    		)
        {
        listBox->SetMarqueeDrawing( ETrue ); //redraw the item without using marquee in the last loop
        listBox->View()->DrawItem( listBox->CurrentItemIndex() );
        listBox->SetMarqueeDrawing(EFalse);
        }
    
    return ETrue;
    }

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
// 
void CMmMarqueeAdapter::SetControl( CEikListBox * aControl )
	{
	iListbox = aControl;
	}

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
// 
TBool CMmMarqueeAdapter::SubcellMarqueeElementExists( TInt aIndex )
	{
	TBool ret = EFalse;
	for (TInt i = 0; i < iMarqueeElements.Count() ; i++)
		{
		if (iMarqueeElements[i]->iSubcellIndex == aIndex)
			{
			ret = ETrue;
			}
		}
	return ret;
	}

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
// 
void CMmMarqueeAdapter::RemoveSubcellMarqueeElement(TInt aSubcellIndex)
	{
	for (TInt i = 0; i < iMarqueeElements.Count() ; i++)
		{
		if (iMarqueeElements[i]->iSubcellIndex == aSubcellIndex)
			{
			iMarqueeElements.Remove(i);
			break;
			}
		}
	}

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
// 
TBool CMmMarqueeAdapter::IsMarqueeEnabled() const
    {
    return iMarqueeEnabled;
    }

//class CMmMarqueeElement

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
// 
CMmMarqueeAdapter::CMmMarqueeElement::CMmMarqueeElement (
		TRect aElementRect,
		CGraphicsContext::TTextAlign aAlign,
		TAknLogicalFontId aFont,
		TRgb aColor, TInt aIndex,
		TInt aBaselineOffset ):iElementRect(aElementRect),
		iAlign(aAlign),
		iFont(aFont),iColor(aColor),
		iSubcellIndex(aIndex),
		iBaselineOffset(aBaselineOffset)
	{

	}


// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
// 
CMmMarqueeAdapter::CMmMarqueeElement::~CMmMarqueeElement ()
	{
	delete iMarqueeControl;
	delete iText;
	}

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
// 
CMmMarqueeAdapter::CMmMarqueeElement* CMmMarqueeAdapter::CMmMarqueeElement::NewL (
		TRect aElementRect, CGraphicsContext::TTextAlign aAlign,
		const TDesC& aText, TAknLogicalFontId aFont, TRgb aColor,TInt aIndex,
		TInt aBaselineOffset )
	{
	CMmMarqueeAdapter::CMmMarqueeElement* self 
		= new (ELeave)CMmMarqueeAdapter::CMmMarqueeElement( aElementRect, aAlign,
				aFont, aColor, aIndex, aBaselineOffset );
	CleanupStack::PushL( self ); 
	self->ConstructL( aText );
	CleanupStack::Pop( self );
	return self;
	}

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
// 		
void CMmMarqueeAdapter::CMmMarqueeElement::ConstructL ( const TDesC& aText )
	{
	iText = aText.AllocL();
	}

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
// 
void CMmMarqueeAdapter::CMmMarqueeElement::SetupMarqueeControlL( 
		TInt aLoops, 
		TInt aScrollAmount, 
		TInt aScrollDelay )
	{
	iMarqueeControl = CAknMarqueeControl::NewL( aLoops, aScrollAmount, aScrollDelay );
	iMarqueeControl->SetLoops(aLoops);
	iLoops = aLoops;
	iScrollAmount = aScrollAmount;
	iScrollDelay = aScrollDelay;
	}
// End of file