uiacceltk/hitchcock/coretoolkit/src/HuiRosterImpl.cpp
changeset 0 15bf7259bb7c
child 3 d8a3531bc6b8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/uiacceltk/hitchcock/coretoolkit/src/HuiRosterImpl.cpp	Tue Feb 02 07:56:43 2010 +0200
@@ -0,0 +1,1709 @@
+/*
+* Copyright (c) 2006-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:   Implementation of CHuiRosterImpl. CHuiRosterImpl implements 
+*                the interface defined by CHuiRoster.
+*
+*/
+
+
+
+#include "HuiRosterImpl.h"  // Class definition
+#include "HuiRosterEntry.h"
+#include "uiacceltk/HuiEnv.h"
+#include "uiacceltk/HuiControlGroup.h"
+#include "uiacceltk/HuiControl.h"
+#include "uiacceltk/HuiDisplay.h"
+#include "uiacceltk/HuiEvent.h"
+#include "uiacceltk/HuiTransformation.h"
+#include "uiacceltk/HuiPanic.h"
+#include "uiacceltk/HuiUtil.h"
+#include "uiacceltk/HuiProbe.h"
+#include "uiacceltk/HuiCanvasVisual.h"
+#include "huilongtapdetector.h"
+#include "HuiFxEffect.h"
+#include "huieffectable.h"
+#include "huicanvasrenderbuffer.h"
+#include "huicanvasgc.h"
+#include "HuiRenderPlugin.h"
+
+#ifdef RD_TACTILE_FEEDBACK
+#include <touchfeedback.h>
+#endif //RD_TACTILE_FEEDBACK
+
+const TReal32 KHuiVisualOutlineWidth = 1.f;
+
+struct THuiPointerEventDetails 
+	{
+	MHuiEventHandler* iEventHandler;
+	THuiXYMetric iXYMetric;
+	TBool iDisableLongTapWhenDragging;
+	TBool iDragging;
+	};
+
+
+
+CHuiRosterImpl::CHuiRosterImpl(CHuiDisplay* aDisplay)
+        : iDisplay(aDisplay), iInitialDownEvent(NULL), iEffectOpacity(1.f)
+    {
+    }
+
+CHuiRosterImpl::~CHuiRosterImpl()
+    {
+    FreezeVisibleContentL(EFalse);
+    
+    delete iLongTapDetector;
+    iEntries.ResetAndDestroy();
+    iPointerDragObservers.Close();
+    iDisplay = NULL;
+    iInputFocus = NULL;
+    iUnhandledPointerObservers.Close();
+    iLongTapObservers.Close();
+    while(iPointerEventDetails.Count()>0)
+    	{
+    	delete iPointerEventDetails[0];
+		iPointerEventDetails.Remove(0);    	
+    	}
+    iPointerEventDetails.ResetAndDestroy();
+    }
+
+
+void CHuiRosterImpl::SetDisplay(CHuiDisplay* aDisplay)
+    {
+    iDisplay = aDisplay;    
+    }
+    
+    
+void CHuiRosterImpl::SetRect(const TRect& aRect)
+    {
+    iRect = TRect(0, 0, aRect.Width(), aRect.Height());
+    UpdateLayout();
+
+    SetChanged();
+    }
+    
+ 
+TRect CHuiRosterImpl::Rect() const
+	{
+	return(iRect);
+	}
+   
+    
+void CHuiRosterImpl::ShowL(CHuiControlGroup& aGroup, TInt aWhere)
+    {
+    // If the group is already shown on the display, just adjust its position
+    // according to the parameters.
+    if(Find(&aGroup) != KErrNotFound)
+        {
+        // It is already shown. Only adjust position.
+        TInt newPos = aWhere;
+        if(newPos == KHuiRosterShowAtTop)
+            {
+            newPos = Count() - 1;
+            }
+        else if(newPos == KHuiRosterShowAtBottom)
+            {
+            newPos = 0;
+            }
+        else
+            {
+            // for PC lint
+            }
+        Move(&aGroup, newPos);            
+        return;
+        }
+
+    if(aWhere == KHuiRosterShowAtTop)
+        {
+        // Put the group on top of the roster.
+        AppendL(&aGroup);
+        }
+    else if(aWhere == KHuiRosterShowAtBottom)
+        {
+        InsertL(&aGroup, 0);
+        }
+    else
+        {
+        InsertL(&aGroup, aWhere);
+        }
+
+    // The group will automatically accept input events once shown.
+    aGroup.SetAcceptInput(ETrue);
+
+    // Show all the controls of the group.
+    for(TInt i = 0; i < aGroup.Count(); ++i)
+        {
+        aGroup.Control(i).ShowL(*iDisplay);
+        }
+    }
+
+
+void CHuiRosterImpl::Hide(CHuiControlGroup& aGroup)
+    {
+    // Hide all the controls of the group.
+    for(TInt i = 0; i < aGroup.Count(); ++i)
+        {
+        aGroup.Control(i).Hide(*iDisplay);
+        }
+
+    Remove(&aGroup);
+    }
+
+
+void CHuiRosterImpl::AppendL(CHuiControlGroup* aGroup)
+    {
+    ASSERT( aGroup );
+    CHuiRosterEntry* entry = new (ELeave) CHuiRosterEntry(*aGroup);
+    CleanupStack::PushL(entry);
+    User::LeaveIfError(iEntries.Append(entry));
+    CleanupStack::Pop(entry);
+
+    if(iDisplay)
+        {
+        iDisplay->Env().ContinueRefresh();
+        }
+        
+    SetChanged();
+    }
+
+
+void CHuiRosterImpl::InsertL(CHuiControlGroup* aGroup, TInt aPos)
+    {
+    ASSERT( aGroup );
+    if(Find(aGroup) != KErrNotFound)
+        {
+        User::Leave(KErrAlreadyExists);
+        }
+
+    CHuiRosterEntry* entry = new (ELeave) CHuiRosterEntry(*aGroup);
+    CleanupStack::PushL(entry);
+    User::LeaveIfError(iEntries.Insert(entry, aPos));
+    CleanupStack::Pop(entry);
+    
+    if(iDisplay)
+        {
+        iDisplay->Env().ContinueRefresh();
+        }
+
+    SetChanged();
+    }
+
+void CHuiRosterImpl::Move(CHuiVisual* aVisual, TInt aPos)
+    {
+    CHuiRosterEntry* entry = EntryForVisual(aVisual);
+    if (entry)
+        {
+        Move(&entry->ControlGroup(), aPos);        
+        }    
+    }
+
+void CHuiRosterImpl::Move(CHuiControlGroup* aGroup, TInt aPos)
+    {
+    TInt index = Find(aGroup);
+    TInt k = 0;
+    
+    if(index != KErrNotFound && index != aPos)
+        {
+        CHuiRosterEntry* moving = iEntries[index];
+        
+        if(aPos > index)
+            {
+            for(k = index; k < aPos; ++k)
+                {
+                iEntries[k] = iEntries[k + 1];
+                }
+            }
+        else 
+            {
+            for(k = index; k > aPos; --k)
+                {
+                iEntries[k] = iEntries[k - 1];
+                }
+            }
+        iEntries[aPos] = moving;                
+        }
+        
+    if(iDisplay)
+        {
+        iDisplay->Env().ContinueRefresh();        
+        }
+
+    SetChanged();
+    }
+
+
+TInt CHuiRosterImpl::Find(CHuiControlGroup* aGroup) const
+    {
+    for(TInt i = 0; i < iEntries.Count(); ++i)
+        {
+        if(&iEntries[i]->ControlGroup() == aGroup)
+            {
+            return i;
+            }
+        }
+    return KErrNotFound;
+    }
+
+
+void CHuiRosterImpl::Remove(CHuiControlGroup* aGroup)
+    {
+    TInt index = Find(aGroup);
+    if(index != KErrNotFound)
+        {
+        delete iEntries[index];
+        iEntries.Remove(index);
+
+        if(iDisplay)
+            {
+            iDisplay->Env().ContinueRefresh();
+            }
+
+        SetChanged();
+        }
+    }
+
+
+TInt CHuiRosterImpl::Count() const
+    {
+    return iEntries.Count();
+    }
+
+
+CHuiControlGroup& CHuiRosterImpl::ControlGroup(TInt aIndex) const
+    {
+    return iEntries[aIndex]->ControlGroup();
+    }
+
+
+CHuiControl* CHuiRosterImpl::FindControl(TInt aControlId) const
+    {
+    CHuiControl* control = 0;
+    for(TInt i = 0; i < iEntries.Count(); ++i)
+        {
+        control = iEntries[i]->ControlGroup().FindControl(aControlId);
+        if(control)
+            {
+            break;
+            }
+        }
+    return control;
+    }
+
+
+CHuiRosterEntry* CHuiRosterImpl::EntryForVisual(const CHuiVisual* aVisual)
+    {
+    ASSERT( aVisual != NULL );
+    CHuiControlGroup* group = aVisual->Owner().ControlGroup();
+    TInt index = Find(group);
+    if(index == KErrNotFound)
+        {
+        // The group is not in this roster.
+        return NULL;
+        }
+    return iEntries[index];
+    }
+
+
+void CHuiRosterImpl::ShowVisualL(CHuiVisual* aVisual)
+    {
+    CHuiRosterEntry* entry = EntryForVisual(aVisual);
+
+    if(!entry)
+        {
+        User::Leave(KErrNotFound);
+        }
+    
+    if(entry->iRootVisuals.Find(aVisual) != KErrNotFound)
+        {
+        User::Leave(KErrAlreadyExists);
+        }
+    
+    User::LeaveIfError( entry->iRootVisuals.Append(aVisual) );
+
+    SetVisualToFullArea(aVisual);    
+    }
+
+
+void CHuiRosterImpl::HideVisual(CHuiVisual* aVisual)
+    {
+    ASSERT( aVisual );
+    aVisual->SetDisplay(NULL);
+    
+    CHuiRosterEntry* entry = EntryForVisual(aVisual);
+    if(entry)
+        {
+        TInt index = entry->iRootVisuals.Find(aVisual);
+        if(index != KErrNotFound) // do nothing if visual was not found
+            {
+            entry->iRootVisuals.Remove(index);
+    
+            if(iDisplay)
+                {
+                iDisplay->Env().ContinueRefresh();
+                }
+            }
+        }
+    }
+
+
+void CHuiRosterImpl::SetFocus(CHuiControl& aControl)
+    {
+    ChangeInputFocus(&aControl);
+    }
+
+
+void CHuiRosterImpl::ClearFocus()
+    {
+    ChangeInputFocus(NULL);
+    }
+
+
+void CHuiRosterImpl::ChangeInputFocus(CHuiControl* aControl)
+    {
+    if(aControl)
+        {
+        // The control must be in one of groups of the roster.
+        CHuiControl* control = FindControl(aControl->Id());
+        if(control != aControl)
+            {
+            // Illegal focus.
+            return;
+            }
+        }
+
+    iInputFocus = aControl;
+    }
+
+TBool CHuiRosterImpl::PrepareDraw() const
+    {
+    HUI_PROBE_PROGRAMFLOW_ENTER(MHuiProbe::EProgramFlowPointRefreshPrepareDraw)
+    
+    TInt i = 0;
+    TInt j = 0;
+
+    TInt visualCount = 0;
+    TInt entryCount = iEntries.Count();
+    // Prepare the visuals tree in the display.
+    for(j = 0; j < entryCount; ++j)
+        {
+        CHuiRosterEntry& entry = *iEntries[j]; 
+        
+        visualCount = entry.iRootVisuals.Count();
+        for(i = 0; i < visualCount; ++i)
+            {
+            CHuiVisual* visual = entry.iRootVisuals[i];
+            //Ignore inactive visuals
+            if ( visual->Flags()& EHuiVisualFlagInactive )
+            	{
+            	continue; 
+            	}
+            TBool successfullyPrepared = ETrue;
+            TRAPD(err, successfullyPrepared = visual->PrepareDrawL());
+            if (err != KErrNone)
+	            {
+	            // Handle the error by calling the visual owner
+	            // errorhandling callback
+                visual->Owner().VisualPrepareDrawFailed(*visual, err);
+
+                HUI_PROBE_PROGRAMFLOW_EXIT(MHuiProbe::EProgramFlowPointRefreshPrepareDraw)
+                return EFalse;
+	            }
+	        if (!successfullyPrepared) 
+		        {
+		        // we can stop preparing the rest of the root visuals
+		        // if one prepare failed (we won't be drawing 
+		        // anything anyway)
+
+		        // also if the prepare failed but it didn't leave,
+		        // we assume it was already handled 
+
+                HUI_PROBE_PROGRAMFLOW_EXIT(MHuiProbe::EProgramFlowPointRefreshPrepareDraw)
+		        return EFalse;
+		        }
+            }
+        }
+
+    HUI_PROBE_PROGRAMFLOW_EXIT(MHuiProbe::EProgramFlowPointRefreshPrepareDraw)
+    return ETrue;
+    }
+
+
+void CHuiRosterImpl::Draw(CHuiGc& aGc) const
+    {
+    Draw(aGc, NULL);
+    }
+
+void CHuiRosterImpl::Draw(CHuiGc& aGc, CHuiDisplay* aDisplay) const
+    {
+    CHuiDisplay* display = aDisplay ? aDisplay : iDisplay;
+    THuiRealRect displayRect = display->VisibleArea();
+    TBool refreshCache = ETrue; // TODO: Could this be optimized ?
+    TBool opaque = EFalse;  
+
+    // Init projection matrix
+    aGc.LoadIdentity(EHuiGcMatrixProjection);
+
+    // Init model matrix 
+    aGc.LoadIdentity(EHuiGcMatrixModel);        
+    
+    // Set up display-specifc window transformations e.g. scaling for tv out        
+    aGc.SetWindowTransformation(&(display->WindowTransformation()));
+    aGc.UpdateProjection();                            
+
+    TBool didDrawEffect = EFalse;
+    if (iEffect)
+        {
+        //RDebug::Print(_L("CHuiRosterImpl::Draw trying to use effect"));
+        TRgb oldColor = aGc.PenColor(); 
+        TInt oldAlpha = aGc.PenAlpha(); 
+
+        // Clear
+        aGc.SetPenColor(KRgbBlack);
+        aGc.SetPenAlpha(0);
+        aGc.Disable(CHuiGc::EFeatureBlending);
+        aGc.Disable(CHuiGc::EFeatureClipping);
+        aGc.Clear();
+
+        // Restore Gc values
+        aGc.SetPenColor(oldColor);
+        aGc.SetPenAlpha(oldAlpha);
+        aGc.Enable(CHuiGc::EFeatureBlending);
+        aGc.Enable(CHuiGc::EFeatureClipping);
+
+        // Note: Opacity implementation in effect system  does not really work visually 
+        // correct if there are semitransparent child windows. Child window opacity becomes too
+        // large, because opacity is applied during visual tree drawing and thus blending child
+        // visuals on top of the parent produces wrong transparency level.
+        //
+        // We workaround this issue here so that we force rendering to cached render
+        // target (with opacity 255) and give the real opacity as a parameter to effect
+        // drawing so the whole operation gets correct opacity. However there is possibility
+        // that complex effect fxml would assume transparency to be handled *before*
+        // some other part of the effect, so this workaround won't work correctly in those cases. 
+        // To get those working, propably whole opacity effect handling should be re-written 
+        // differently.
+        if (iEffect->IsSemitransparent() || iEffectOpacity < 1.f)
+            {
+            iEffect->ForceCachedRenderTargetUsage(ETrue);
+            }        
+        RRegion dummy;
+        didDrawEffect = iEffect->CachedDraw(aGc, displayRect, refreshCache, opaque, dummy, iEffectOpacity*255);        
+        dummy.Close();
+        }
+    
+    if (!didDrawEffect)
+        {
+        DrawSelf(aGc, aDisplay);
+        }
+    else
+        {
+        // Effect was drawn, OpenGLES/OpenVG may be in different state than what Gc thinks so we restore it.
+        aGc.RestoreState();                
+        }
+
+    // Undo display-specifc window transformations                          
+    aGc.SetWindowTransformation(NULL);
+    aGc.UpdateProjection();            
+
+    // Undo changes to model matrix
+    aGc.LoadIdentity(EHuiGcMatrixModel);    
+    }
+
+void CHuiRosterImpl::DrawSelf(CHuiGc& aGc, CHuiDisplay* aDisplay) const
+    {
+    HUI_PROBE_PROGRAMFLOW_ENTER(MHuiProbe::EProgramFlowPointRefreshDraw)
+
+    TInt i = 0;
+    TInt j = 0;
+
+    CHuiDisplay* display = aDisplay ? aDisplay : iDisplay;
+
+    if (iCanvasRenderBuffer && iCanvasGc)
+        {
+        DrawSelfFrozen(aGc, aDisplay);
+        return;
+        }
+
+    TInt visualCount = 0;
+    TInt entryCount = iEntries.Count();
+    // Draw the visuals tree in the display.
+    for(j = 0; j < entryCount; ++j)
+        {
+        CHuiRosterEntry& entry = *iEntries[j]; 
+        CHuiControlGroup& group = entry.ControlGroup();
+
+        // Init model matrix always for every group
+        //aGc.LoadIdentity(EHuiGcMatrixModel);        
+        aGc.Push(EHuiGcMatrixModel);
+        
+        // Set up display-specifc transformations i.e. camera transformations    	
+        display->Transformation().Execute(EHuiGcMatrixModel, aGc);
+        
+        // Set up a group-specific transformation.
+        if(group.IsTransformed())
+            {
+   	        group.Transformation().Execute(EHuiGcMatrixModel, aGc);
+            }
+        
+        // Draw visuals
+        visualCount = entry.iRootVisuals.Count();
+        for(i = 0; i < visualCount; ++i)
+            {
+            CHuiVisual* visual = entry.iRootVisuals[i];
+            //Ignore inactive visuals
+            if ( visual->Flags()& EHuiVisualFlagInactive || visual->LoadingEffect() )
+            	{
+            	continue; 
+            	}
+            visual->Draw(aGc);
+            }       
+
+        if( display->DrawVisualOutline() != CHuiDisplay::EDrawVisualOutlineNone )
+            {        	
+            for(i = 0; i < visualCount; ++i)
+                {	
+                // Draw Visual Outline depending on central repository setting
+                // and visual flag value
+                const TBool drawOutline =
+                    ( entry.iRootVisuals[i]->Flags() & EHuiVisualFlagEnableDebugMode ) ||  
+                    ( display->DrawVisualOutline() == CHuiDisplay::EDrawVisualOutlineAllVisuals );
+                
+                DrawBoundaries( aGc, entry.iRootVisuals[i], drawOutline );        
+                }
+            }
+        
+        aGc.Pop(EHuiGcMatrixModel);        
+        }
+    
+    HUI_PROBE_PROGRAMFLOW_EXIT(MHuiProbe::EProgramFlowPointRefreshDraw)
+    }
+
+void CHuiRosterImpl::DrawSelfFrozen(CHuiGc& aGc, CHuiDisplay* aDisplay) const
+    {
+    if (iCanvasGc && iCanvasRenderBuffer)
+        {
+        iCanvasGc->SetGc(aGc);
+        iCanvasGc->SetDefaults();
+        iCanvasGc->PushTransformationMatrix();
+                
+        // Calculate rotation as relative to the current display rotation.
+        CHuiGc::TOrientation relativeOrientation = CHuiGc::EOrientationNormal;    
+        CHuiGc::TOrientation displayOrientation = aDisplay->Orientation(); 
+        CHuiGc::TOrientation renderBufferOrientation = iCanvasRenderBufferOrientation; 
+        
+        TInt rotationAngle[] =
+            {
+            0, 
+            270, 
+            90, 
+            180
+            };
+            
+        TInt displayOrientationAngle = rotationAngle[displayOrientation];
+        TInt renderBufferOrientationAngle = rotationAngle[renderBufferOrientation];    
+        TInt relativeOrientationAngle = renderBufferOrientationAngle - displayOrientationAngle;
+        
+        // Check over/underflow
+        if (relativeOrientationAngle > 360)
+            {
+            relativeOrientationAngle -= 360;
+            }
+        else if (relativeOrientationAngle < 0)
+            {
+            relativeOrientationAngle += 360;
+            }
+        
+        switch (relativeOrientationAngle)
+            {
+            case 0:
+                {
+                relativeOrientation = CHuiGc::EOrientationNormal;
+                break;
+                }
+            case 90:
+                {
+                relativeOrientation = CHuiGc::EOrientationCW90;            
+                break;
+                }
+            case 270:
+                {
+                relativeOrientation = CHuiGc::EOrientationCCW90;            
+                break;
+                }
+            case 180:
+                {
+                relativeOrientation = CHuiGc::EOrientation180;            
+                break;
+                }
+            default:
+                {
+                // As usual, this should not happen...but just in case it does use normal rotation
+                relativeOrientation = CHuiGc::EOrientationNormal;
+                break;
+                }        
+            }
+        
+        TRect displayArea = aDisplay->VisibleArea();
+        TInt w = displayArea.Width();
+        TInt h = displayArea.Height();
+
+       
+        // ...select right rotation...
+        if (relativeOrientation == CHuiGc::EOrientationCW90)
+            {
+            // Rotate around origo and move back to displayarea
+            iCanvasGc->Rotate(-90, 0, 0, 1.f);
+            iCanvasGc->Translate(-h, 0, 0);
+            }
+        else if (relativeOrientation == CHuiGc::EOrientationCCW90)
+            {
+            // Rotate around origo and move back to displayarea
+            iCanvasGc->Rotate(90, 0, 0, 1.f);
+            iCanvasGc->Translate(0, -w, 0);
+            }
+        else if (relativeOrientation == CHuiGc::EOrientation180)
+            {
+            // Rotate around origo and move back to displayarea
+            iCanvasGc->Rotate(180, 0, 0, 1.f);
+            iCanvasGc->Translate(-w, -h, 0);            
+            }
+        else
+            {
+            // Nothing
+            }            
+
+        // Pixels are upside down in OpenVG canvas render buffer
+        if (CHuiStatic::Env().Renderer() == EHuiRendererVg10)
+            {
+            TInt height = h;
+            if (relativeOrientation == CHuiGc::EOrientationCW90 || relativeOrientation == CHuiGc::EOrientationCCW90)
+                {
+                height = w;    
+                }            
+            iCanvasGc->Translate(0.0f, height, 0.0f);            
+            iCanvasGc->Scale(1.f, -1.f, 1.f);
+            }
+        
+        iCanvasGc->DrawImage(*iCanvasRenderBuffer, TPoint(0,0));        
+        iCanvasGc->PopTransformationMatrix();
+        }
+    }
+
+void CHuiRosterImpl::DrawBoundaries( CHuiGc& aGc, CHuiVisual* aVisual, TBool aDrawOutline ) const
+	{
+    if( aDrawOutline )
+        {
+        const THuiRealRect content = aVisual->DisplayRect();
+        
+        if (aVisual->Flags()& EHuiVisualFlagInactive)
+            {
+            aGc.SetPenColor( KRgbDarkGray );           
+            }
+        else
+            {
+            aGc.SetPenColor( TUint32(aVisual)&0x00ffffff/*KRgbBlack*/ );  // Use "random" color
+            }
+        aGc.DrawBorders(content.Round(), 
+            KHuiVisualOutlineWidth, KHuiVisualOutlineWidth,
+            KHuiVisualOutlineWidth, KHuiVisualOutlineWidth,
+            CHuiGc::EBorderFixedCorners);
+        }
+        
+    for( TInt k = 0; k < aVisual->Count(); ++k )
+        {
+        DrawBoundaries( 
+            aGc, 
+            &aVisual->Visual( k ), 
+            ( (  aVisual->Visual( k ).Flags() & EHuiVisualFlagEnableDebugMode ) || 
+                aDrawOutline ) );
+        }
+    }
+
+
+TBool CHuiRosterImpl::HasTransformedControlGroups() const
+    {
+    TInt j = 0;
+    for(j = 0; j < iEntries.Count(); ++j)
+        {
+        CHuiRosterEntry& entry = *iEntries[j]; 
+        CHuiControlGroup& group = entry.ControlGroup();
+        if(group.IsTransformed())
+            {
+            return ETrue;    
+            }
+        }
+    return EFalse;    
+    }
+
+
+TBool CHuiRosterImpl::HandleEventL(const THuiEvent& aEvent)
+    {
+    TInt i = 0;
+    TInt k = 0;
+
+    if(iDisplay)
+        {
+        iDisplay->Env().ContinueRefresh();
+        }
+
+    if(aEvent.IsPointerEvent())
+        {
+        iTactileFeedbackHandled = EFalse;
+        
+        // Put event details array up to date
+        CleanEventDetails();
+        
+        if ( !iLongTapDetector )
+            {
+            iLongTapDetector = CHuiLongTapDetector::NewL( *this );
+            }
+        iLongTapDetector->OfferPointerEvent( aEvent );
+        
+        if ( aEvent.PointerDown() )
+        	{
+        	iInitialDownEvent = aEvent;
+        	CleanDraggingFlags();
+        	}
+		
+        
+        // Restricted distribution?
+        if(aEvent.iPointerEvent.iType == TPointerEvent::EDrag)
+            {
+            // Only send these if there are observers.
+            for(i = 0; i < iPointerDragObservers.Count(); ++i)
+                {
+                if( DragEventOutOfRangeL( &iPointerDragObservers[i], aEvent) )
+                	{
+	                if(iPointerDragObservers[i].OfferEventL(aEvent))
+	                    {
+	                    return ETrue;
+	                    }                                    	
+                	}
+                }
+            return EFalse;
+            }
+            
+        // The event is generated by the long tap detector
+        if(aEvent.iPointerEvent.iType == TPointerEvent::EButtonRepeat)
+            {
+            // Only send these if there are observers.
+            for(i = 0; i < iLongTapObservers.Count(); ++i)
+                {
+                if(IsLongTapEventAllowed(&iLongTapObservers[i]))
+                	{
+	                if(iLongTapObservers[i].OfferEventL(aEvent))
+	                    {
+	                    return ETrue;
+	                    }                	
+                	}
+                }
+            return EFalse;
+            }  
+        
+        // The other pointer events are offered depending on the visuals.
+        for(i = iEntries.Count() - 1; i >= 0; --i)
+            {
+            CHuiRosterEntry& entry = *iEntries[i];
+            CHuiControlGroup& group = entry.ControlGroup();
+            
+            if(!group.AcceptInput())
+                {
+                // The group will not be receiving input events.
+                continue;
+                }
+           
+            for(k = entry.iRootVisuals.Count() - 1; k >= 0; --k)
+                {
+                if(OfferPointerEventWithinTreeL(*entry.iRootVisuals[k], aEvent))
+                    {
+                    return ETrue;
+                    }
+                }    
+                
+            // Offer to the fallback handlers of the group.
+            for(k = 0; k < group.iUnhandledEventObservers.Count(); ++k)
+                {
+                if(group.iUnhandledEventObservers[k].OfferEventL(aEvent))
+                    {
+                    return ETrue;
+                    }
+                }
+            }
+            
+        // No one handled the event.
+        for(i = 0; i < iUnhandledPointerObservers.Count(); ++i)
+            {
+            if(iUnhandledPointerObservers[i].OfferEventL(aEvent))
+                {
+                return ETrue;
+                }
+            }
+        }
+    else 
+        {
+        // First offer to the input control.
+        if(aEvent.IsKeyEvent() && iInputFocus && iInputFocus->AcceptInput())
+            {
+            if(iInputFocus->OfferEventL(aEvent))
+                {
+                return ETrue;
+                }
+            }
+
+        // Iterate through the groups and controls in priority order.
+        for(i = iEntries.Count() - 1; i >= 0; --i)
+            {
+            CHuiControlGroup& group = iEntries[i]->ControlGroup();
+            
+            if(!group.AcceptInput())
+                {
+                // The group will not be receiving input events.
+                continue;
+                }
+            
+            for(k = group.Count() - 1; k >= 0; --k)
+                {
+                CHuiControl& control = group.Control(k);
+                if(control.OfferEventL(aEvent))
+                    {
+                    // The event was consumed, now it can't be handled by
+                    // anyone else.
+                    return ETrue;
+                    }
+                }
+            // Notify observer that group didn't handle event?
+            }
+        }
+
+    return EFalse;
+    }
+    
+    
+TBool CHuiRosterImpl::OfferPointerEventWithinTreeL(CHuiVisual& aVisual, const THuiEvent& aEvent, TBool aUseDispRect)
+    {
+    //Ignore inactive visuals
+    if( ( aVisual.Flags() & EHuiVisualFlagIgnorePointer ) || 
+    		( aVisual.Flags() & EHuiVisualFlagInactive ) )
+        {
+        // Discard the entire branch of visuals.
+        return EFalse;
+        }
+
+    const TPoint& pos = aEvent.iPointerEvent.iPosition;
+    
+    TBool useDispRect = EFalse;
+    // If it has children, offer to those first.
+    for(TInt i = aVisual.Count() - 1; i >= 0; --i)
+        {
+        // set useDispRect, if scroll is enabled on a layout
+        useDispRect = static_cast<CHuiLayout&>(aVisual).Scrolling();
+        
+        if(OfferPointerEventWithinTreeL(aVisual.Visual(i), aEvent, useDispRect))
+            {
+            return ETrue;
+            }
+        }
+            
+    TRect visualRect;
+    if(aUseDispRect)
+        {
+        visualRect = TRect(aVisual.DisplayRect());
+        }
+    else
+        {
+        // use cashed display rect
+        visualRect = TRect(aVisual.CachedDisplayRect());
+        }
+    
+    // Offer to the visual itself.
+    if(visualRect.Contains(pos))
+        {
+        HUI_DEBUG3(_L("CHuiRosterImpl::OfferPointerEventWithinTreeL: aVisual=%x pos=%i,%i"), 
+            &aVisual, pos.iX, pos.iY);
+
+        MHuiEventHandler* handler = aVisual.Owner().EventHandler();
+        if(handler)
+            {
+            THuiEvent eventWithVisual = aEvent;
+            eventWithVisual.SetVisual(&aVisual);
+            HandleTactileFeedback( eventWithVisual );
+            if(handler->OfferEventL(eventWithVisual))
+                {
+                return ETrue;
+                }
+            }
+        }
+        
+    // Not consumed.
+    return EFalse;        
+    }
+    
+    
+TBool CHuiRosterImpl::Changed() const
+    {
+    if(iChanged)
+        {
+        return ETrue;
+        }
+    
+    TInt entryCount = iEntries.Count();
+    for(TInt i = 0; i < entryCount; ++i)
+        {
+        if(iEntries[i]->ControlGroup().Changed())
+            {
+            return ETrue;
+            }
+        }
+
+    if (iEffect && iEffect->Changed())
+        {
+        return ETrue;
+        }
+                        
+    return EFalse;        
+    }
+    
+    
+void CHuiRosterImpl::ScanDirty()
+    {
+    if(Changed())
+        {
+        // If the entire roster has changed, there is no need to query 
+        // individual visuals.
+        if(iDisplay)
+            {
+            iDisplay->AddDirtyRegion(iRect);
+            }
+        
+        SetChanged(EFalse);
+        return;
+        }
+    
+    if (iDisplay && !iDisplay->IsDirtyScanNeeded())
+        {
+        // Dirty scan is not needed, we can return directly.
+        return;    
+        }
+    
+    TInt entryCount = iEntries.Count();
+    for(TInt j = 0; j < entryCount; ++j)
+        {
+        CHuiRosterEntry& entry = *iEntries[j]; 
+        TInt count = entry.iRootVisuals.Count();
+        for(TInt i = 0; i < count; ++i)
+            {
+            //Ignore inactive visuals
+            if ( entry.iRootVisuals[i]->Flags()& EHuiVisualFlagInactive )
+           		{
+           		continue; 
+           		}
+            entry.iRootVisuals[i]->ReportChanged();
+            }
+        }
+    }
+
+
+// This ScanDirty-method supports transformed dirty rects
+void CHuiRosterImpl::ScanTransformedDirty(CHuiGc& aGc, CHuiDisplay* aDisplay)
+    {
+    CHuiDisplay* display = aDisplay ? aDisplay : iDisplay;
+
+    // Init projection matrix
+    aGc.LoadIdentity(EHuiGcMatrixProjection);
+
+    // Set up display-specifc window transformations e.g. scaling for tv out    	
+    aGc.SetWindowTransformation(&(display->WindowTransformation()));
+    aGc.UpdateProjection();                            
+
+    if(Changed()) 
+        {
+        // If the entire roster has changed, there is no need to query 
+        // individual visuals.
+        if(display)
+            {
+            display->AddDirtyRegion(iRect);
+            }
+        
+        SetChanged(EFalse);
+        }
+    
+    for(TInt j = 0; j < iEntries.Count(); ++j)
+    	{
+        if (display && !display->IsDirtyScanNeeded())
+        	{
+            break;    
+            }
+
+        CHuiRosterEntry& entry = *iEntries[j]; 
+        CHuiControlGroup& group = entry.ControlGroup();
+
+        // Init model matrix always for every group
+        aGc.LoadIdentity(EHuiGcMatrixModel);        
+            
+        // Set up display-specifc transformations i.e. camera transformations    	
+        __ASSERT_DEBUG(display, USER_INVARIANT());
+        display->Transformation().Execute(EHuiGcMatrixModel, aGc);
+            
+        // Set up a group-specific transformation.
+        if(group.IsTransformed())
+            {
+            group.Transformation().Execute(EHuiGcMatrixModel, aGc);
+            }
+
+        for(TInt i = 0; i < entry.iRootVisuals.Count(); ++i)
+            {
+            if (display && !display->IsDirtyScanNeeded())
+                {
+                break;    
+                }
+            //Ignore inactive visuals     
+            if ( entry.iRootVisuals[i]->Flags()& EHuiVisualFlagInactive )
+           		{
+                continue;
+           		}
+            entry.iRootVisuals[i]->ReportChanged();
+            }
+        }
+
+    // Undo display-specifc window transformations                          
+    aGc.SetWindowTransformation(NULL);
+    aGc.UpdateProjection();            
+
+    // Undo changes to model matrix
+    aGc.LoadIdentity(EHuiGcMatrixModel);
+    }
+
+
+void CHuiRosterImpl::MoveVisualToFront(CHuiVisual* aRootVisual)
+    {
+    ASSERT( aRootVisual );
+    MoveVisualToFront(*aRootVisual);
+    }
+
+
+void CHuiRosterImpl::MoveVisualToFront(const CHuiVisual& aRootVisual)
+    {
+    CHuiRosterEntry* entry = EntryForVisual(&aRootVisual);
+    __ASSERT_ALWAYS( entry != NULL, THuiPanic::Panic(THuiPanic::ERosterGroupNotFound) );
+    TInt index = entry->iRootVisuals.Find(&aRootVisual);
+    if(index == KErrNotFound)
+        {
+        /** @todo Panic? */
+        return;
+        }
+        
+    entry->iRootVisuals.Remove(index);
+    entry->iRootVisuals.Append(&aRootVisual);        
+    
+    UpdateLayout();
+    }
+    
+     
+void CHuiRosterImpl::UpdateLayout()
+    {
+    SetChanged();
+    
+    TInt visualCount = 0;
+    TInt entryCount = iEntries.Count();
+    for(TInt i = 0; i < entryCount; ++i)
+        {
+        visualCount = iEntries[i]->iRootVisuals.Count();
+        for(TInt j = 0; j < visualCount; ++j)
+            {
+            //Ignore inactive visuals
+            if ( iEntries[i]->iRootVisuals[j]->Flags()& EHuiVisualFlagInactive )
+            	{
+            	continue;
+            	}
+            SetVisualToFullArea(iEntries[i]->iRootVisuals[j]);
+            }
+        }
+    }    
+
+
+void CHuiRosterImpl::SetVisualToFullArea(CHuiVisual* aVisual)
+    {
+    ASSERT( aVisual );
+    
+    TInt globalTransitionTime = CHuiStatic::LayoutTransitionTime();
+    
+    // Root visuals are automatically full size.
+    /** @todo  Needs a better way to set the visual's display. */
+    if(iDisplay)
+        {
+        aVisual->SetDisplay(iDisplay);
+        iDisplay->Env().ContinueRefresh();
+        }
+    
+    if(!(aVisual->Flags() & EHuiVisualFlagManualPosition))
+        {
+        aVisual->SetPos(iRect.iTl, globalTransitionTime);
+        }
+
+    if(!(aVisual->Flags() & EHuiVisualFlagManualSize))
+        {
+        aVisual->SetSize(iRect.Size(), globalTransitionTime);
+        }
+    else
+        {
+        aVisual->UpdateChildrenLayout(globalTransitionTime);
+        }
+        
+    aVisual->ReportLayoutUpdate();        
+    }
+
+
+void CHuiRosterImpl::NotifySkinChangedL()
+    {
+    TInt visualCount = 0;
+    TInt entryCount = iEntries.Count();
+    for(TInt j = 0; j < entryCount; ++j)
+        {
+        CHuiRosterEntry& entry = *iEntries[j];
+        visualCount = entry.iRootVisuals.Count();
+        for(TInt i = 0; i < visualCount; ++i)
+            {
+            //Ignore inactive visuals
+            if ( entry.iRootVisuals[i]->Flags()& EHuiVisualFlagInactive )
+            	{
+            	continue;	
+            	}
+            entry.iRootVisuals[i]->NotifySkinChangedL();
+            }
+        }
+    }
+
+
+void CHuiRosterImpl::DumpRootLevelTrees() const
+    {
+    TInt visualCount = 0;
+    TInt entryCount = iEntries.Count();
+    for(TInt j = 0; j < entryCount; ++j)
+        {
+        CHuiRosterEntry& entry = *iEntries[j];
+        visualCount = entry.iRootVisuals.Count();
+        for(TInt i = 0; i < visualCount; ++i)
+            {
+            CHuiVisual* visual = entry.iRootVisuals[i];
+            visual->DumpTree();
+            }
+        }
+    }
+
+
+void CHuiRosterImpl::ClearChanged()
+    {
+    HUI_DEBUGF(_L("CHuiRosterImpl::ClearChanged() - Clearing all change flags."));
+    
+    TInt visualCount = 0;
+    TInt entryCount = iEntries.Count();
+    for(TInt j = 0; j < entryCount; ++j)
+        {
+        CHuiRosterEntry& entry = *iEntries[j];
+        visualCount = entry.iRootVisuals.Count();
+        for(TInt i = 0; i < visualCount; ++i)
+            {
+            // Ignore inactive visuals
+            if ( entry.iRootVisuals[i]->Flags()& EHuiVisualFlagInactive )
+                {
+                continue; 
+                }
+            
+            // This will clear the change flags of the entire tree of visuals.
+            entry.iRootVisuals[i]->ClearChanged();
+            }
+        }
+    }
+
+
+void CHuiRosterImpl::SetChanged(TBool aIsChanged)
+    {
+    if(aIsChanged && !iChanged)
+        {
+        HUI_DEBUG(_L("CHuiRosterImpl::SetChanged() - Roster flagged as changed."));
+        }
+    else if(!aIsChanged && iChanged)
+        {
+        HUI_DEBUG(_L("CHuiRosterImpl::SetChanged() - Roster change flag cleared."));
+        }
+    else
+        {
+        // for PC lint
+        }
+        
+    iChanged = aIsChanged;
+    }
+
+
+RHuiObserverArray<MHuiEventHandler>& CHuiRosterImpl::Observers(THuiInputType aInputType)
+    {
+    switch(aInputType)
+        {
+        case EHuiInputPointerDrag:
+            return iPointerDragObservers;
+            
+        case EHuiInputPointerLongTap:
+            return iLongTapObservers;
+
+        case EHuiInputPointerUnhandled:
+            return iUnhandledPointerObservers;
+            
+        default:
+            HUI_PANIC(THuiPanic::ERosterUnknownInputObserverType)
+            return iPointerDragObservers; // never reached
+        }
+    }
+    
+void CHuiRosterImpl::HandleTactileFeedback( const THuiEvent& aEvent )
+    {
+    // If tactile feedback has been already deciede for this event....
+    if ( iTactileFeedbackHandled )
+        {
+        return;
+        }
+    
+    // The tactile feedback is defined on visual basis
+    if ( !aEvent.Visual() )
+        {
+        // no visual, no feedback
+        return;
+        }
+        
+    // Only pointer events
+    if ( !aEvent.IsPointerEvent() )
+        {
+        return;
+        }
+        
+    // Currently support only pointer down events
+    if ( !aEvent.PointerDown() )
+        {
+        return;
+        }
+        
+    const TInt eventType = 0; // = ETouchEventStylusDown
+    
+    // Check if the viusal has a tactile feedback specified
+    const TInt feedbackType = aEvent.Visual()->TactileFeedback( eventType );
+    
+    if ( feedbackType != KErrNotFound )
+        {
+        iTactileFeedbackHandled = ETrue; // Handling it now.
+        
+#ifdef RD_TACTILE_FEEDBACK
+        MTouchFeedback* feedback = MTouchFeedback::Instance();
+        if ( feedback )
+            {
+            feedback->InstantFeedback( (TTouchLogicalFeedback)feedbackType );
+            }   
+#else
+
+#ifdef _DEBUG
+        // for RnD
+        switch( feedbackType )
+            {
+            case 0: // none
+                User::InfoPrint( _L("None") );
+                break;
+            case 1: // basic
+                User::InfoPrint( _L("Basic") );
+                break;
+            case 2: // sensitive
+                User::InfoPrint( _L("Sensitive") );
+                break;
+            default:
+                break;
+            }
+#endif // _DEBUG
+
+#endif
+        }
+    }
+
+// Adds new detail entry to iPointerEventDetails
+void CHuiRosterImpl::AddEventDetailsL(MHuiEventHandler* aEventHandler, const THuiXYMetric& aXYMetric, TBool aDisable)
+	{
+	THuiPointerEventDetails* newDetails = new (ELeave) THuiPointerEventDetails;
+	newDetails->iEventHandler = aEventHandler;
+	newDetails->iXYMetric = aXYMetric;
+	newDetails->iDisableLongTapWhenDragging = aDisable;
+	newDetails->iDragging = EFalse;	
+	TInt err = iPointerEventDetails.Append(newDetails);
+	if ( err != KErrNone )
+	    {
+	    delete newDetails;
+	    User::Leave( err );
+	    }
+	}
+	
+// Cleans entries from iPointerEventDetails if there isn't observer for 
+// that event handler
+void CHuiRosterImpl::CleanEventDetails()
+	{
+	TInt i = 0;
+	
+	while(i < iPointerEventDetails.Count())
+		{
+		TBool used = EFalse;
+		
+		// Check in drag observers
+		for(TInt j = 0; j < iPointerDragObservers.Count(); ++j)
+			{
+			if(iPointerEventDetails[i]->iEventHandler == &iPointerDragObservers[j])
+				{
+				used = ETrue;
+				break;
+				}
+			}
+
+		// Check in long tap observers
+		if(!used) 
+			{
+			for(TInt j = 0; j < iLongTapObservers.Count(); ++j)
+				{
+				if(iPointerEventDetails[i]->iEventHandler == &iLongTapObservers[j])
+					{
+					used = ETrue;
+					break;
+					}
+				}			
+			}
+			
+		// Check in unhandled observers
+		if(!used) 
+			{
+			for(TInt j = 0; j < iUnhandledPointerObservers.Count(); ++j)
+				{
+				if(iPointerEventDetails[i]->iEventHandler == &iUnhandledPointerObservers[j])
+					{
+					used = ETrue;
+					break;
+					}
+				}
+			}
+		
+		// If event handler isn't found in observers, we remove details for that
+		// event handler from iPointerEventDetails
+		if(!used)
+			{
+			delete iPointerEventDetails[i];
+			iPointerEventDetails.Remove(i);
+			}
+		else
+			{
+			i++;
+			}
+		}	
+	}
+
+// Cleans dragging flags in iPointerEventDetails
+void CHuiRosterImpl::CleanDraggingFlags()
+	{
+	for(TInt i = 0; i < iPointerEventDetails.Count(); ++i)
+		{
+		iPointerEventDetails[i]->iDragging = EFalse;
+		}
+	}
+
+// Sets treshold which pointer needs to be moved before starting to send drag events.
+void CHuiRosterImpl::SetPointerDragThresholdL(const MHuiEventHandler& aEventHandler, const THuiXYMetric& aXYMetric)
+	{		
+	MHuiEventHandler *handler = (MHuiEventHandler*)&aEventHandler;
+
+	// Check if there is already detail entry in iPointerEventDetails where to update
+	// details
+	for(TInt i = 0; i < iPointerEventDetails.Count(); ++i)
+		{
+		if(iPointerEventDetails[i]->iEventHandler == handler)
+			{
+			iPointerEventDetails[i]->iXYMetric = aXYMetric;
+			return;
+			}					
+		}
+	
+	// If event handler wasn't found, we add new detail entry
+	AddEventDetailsL(handler, aXYMetric, EFalse);
+	}
+	
+// Disables long tap events when dragging is going on. 
+void  CHuiRosterImpl::DisableLongTapEventsWhenDraggingL(const MHuiEventHandler& aEventHandler, TBool aDisable)
+	{
+	MHuiEventHandler* handler = const_cast<MHuiEventHandler*>( &aEventHandler );
+	
+	// Check if there is already detail entry in iPointerEventDetails where to update
+	// details
+	for(TInt i = 0; i < iPointerEventDetails.Count(); ++i)
+		{
+		if(iPointerEventDetails[i]->iEventHandler == handler)
+			{
+			iPointerEventDetails[i]->iDisableLongTapWhenDragging = aDisable;
+			return;
+			}
+		}	
+
+	// If event handler wasn't found, we add new detail entry
+	AddEventDetailsL(handler, THuiXYMetric(KDefaultDragTresholdInPixelsX, KDefaultDragTresholdInPixelsY), aDisable);
+	}
+
+// Checks if event handler is within threshold range.
+TBool CHuiRosterImpl::DragEventOutOfRangeL(MHuiEventHandler* aEventHandler, const THuiEvent& aEvent)
+	{	
+ 	if ( aEvent.IsPointerEvent() && iInitialDownEvent.IsPointerEvent())
+        {
+		TBool handlerFound = EFalse;
+		
+		// Find event handler from detail array
+		for(TInt i = 0; i < iPointerEventDetails.Count(); ++i)
+			{
+			if(iPointerEventDetails[i]->iEventHandler == aEventHandler)
+				{
+				
+				// If we are already sending dragging events to this handler
+				// we can return immediately
+				if(iPointerEventDetails[i]->iDragging) 
+					{
+					return ETrue;
+					}
+					
+				handlerFound = ETrue;
+				
+				// calculate moved distance in pixels
+				TPoint result = iInitialDownEvent.iPointerEvent.iPosition-aEvent.iPointerEvent.iPosition;
+								
+				// Do metric calculations
+			    THuiRealPoint tresholdInPx(iPointerEventDetails[i]->iXYMetric.iX.iMagnitude, iPointerEventDetails[i]->iXYMetric.iY.iMagnitude);
+			    if(iPointerEventDetails[i]->iXYMetric.iX.iUnit != EHuiUnitPixel) 
+			    	{
+			    	TReal32 reference = 0;
+			    	if (iPointerEventDetails[i]->iXYMetric.iX.iUnit == EHuiUnitRelativeToDisplay && iDisplay ) 
+			    		{
+			    		reference = iDisplay->VisibleArea().Width();
+			    		}
+			    	if (iPointerEventDetails[i]->iXYMetric.iX.iUnit == EHuiUnitS60  && iDisplay ) 
+			    		{
+			    		reference = iDisplay->UnitValue();
+			    		}			    		
+			    	tresholdInPx.iX = tresholdInPx.iX * reference;
+			    	}
+			    if(iPointerEventDetails[i]->iXYMetric.iY.iUnit != EHuiUnitPixel) 
+			    	{
+			    	TReal32 reference = 0;
+			    	if (iPointerEventDetails[i]->iXYMetric.iY.iUnit == EHuiUnitRelativeToDisplay && iDisplay ) 
+			    		{
+			    		reference = iDisplay->VisibleArea().Width();
+			    		}
+			    	if (iPointerEventDetails[i]->iXYMetric.iY.iUnit == EHuiUnitS60  && iDisplay ) 
+			    		{
+			    		reference = iDisplay->UnitValue();
+			    		}			    		
+			    	tresholdInPx.iY = tresholdInPx.iY * reference;
+			    	}
+			    
+			    // Check if we are outside of the threshold
+				if (result.iX < -tresholdInPx.iX || result.iX > tresholdInPx.iX||
+					result.iY < -tresholdInPx.iY ||	result.iY > tresholdInPx.iY	) 
+					{
+					iPointerEventDetails[i]->iDragging = ETrue;					
+					return ETrue;						
+					}
+				else
+					{
+					iPointerEventDetails[i]->iDragging = EFalse;
+					}
+				}
+			}
+			
+		// If no event handler found in iPointerEventDetails array,
+		// check with default threshold.
+		if(!handlerFound) 
+			{
+			TPoint result = iInitialDownEvent.iPointerEvent.iPosition-aEvent.iPointerEvent.iPosition;
+								
+			if (result.iX < -KDefaultDragTresholdInPixelsX || result.iX > KDefaultDragTresholdInPixelsX||
+				result.iY < -KDefaultDragTresholdInPixelsY || result.iY > KDefaultDragTresholdInPixelsY) 
+				{
+				// We need to add new event detail to store dragging flag
+				AddEventDetailsL(aEventHandler, THuiXYMetric(KDefaultDragTresholdInPixelsX, KDefaultDragTresholdInPixelsY), EFalse);
+				return DragEventOutOfRangeL(aEventHandler, aEvent);
+				}			
+			}		
+        }	
+	return EFalse;
+	}
+
+// Checks if long tap event is allowed to send.
+TBool CHuiRosterImpl::IsLongTapEventAllowed(MHuiEventHandler* aEventHandler)
+	{
+	for(TInt i = 0; i < iPointerEventDetails.Count(); ++i)
+		{
+		if(iPointerEventDetails[i]->iEventHandler == aEventHandler)
+			{
+			if ( iPointerEventDetails[i]->iDragging ) 
+				{
+				return !(iPointerEventDetails[i]->iDisableLongTapWhenDragging);				
+				}
+			}	
+        }	
+	return ETrue;
+	}
+
+
+void CHuiRosterImpl::SetDrawingExternalContent(TBool aEnable)
+	{
+	iDrawEvenIfDisabledDrawInRoster = aEnable;
+	}
+
+	
+TBool CHuiRosterImpl::IsDrawingExternalContent() const
+	{
+	return iDrawEvenIfDisabledDrawInRoster;
+	}
+
+void CHuiRosterImpl::RemoveExternalContentVisualFromParentL(CHuiVisual* aExternalContentVisual)
+    {
+    // External content is only used with canvas visuals, and the layouts of canvas visuals are always in the roster.
+    // Browse all layouts in the roster and check if they have a canvas visual as a child visual.
+    // Note: this can be slow operation, so it should only be done rarely.
+   
+    TInt visualCount = 0;
+    TInt entryCount = iEntries.Count();    
+    for(TInt j = 0; j < entryCount; ++j)
+    	{
+    	CHuiRosterEntry& entry = *iEntries[j]; // control group
+    	visualCount = entry.iRootVisuals.Count();
+        for(TInt i = 0; i < visualCount; ++i)
+        	{
+        	CHuiLayout* layout = dynamic_cast<CHuiLayout*>(entry.iRootVisuals[i]); // layout
+        	
+        	if (layout)
+        		{
+        		RemoveExternalContentVisualFromParentL(aExternalContentVisual,layout);
+        		}
+        	} 	
+    	}
+    }
+
+void CHuiRosterImpl::RemoveExternalContentVisualFromParentL(CHuiVisual* aExternalContentVisual, CHuiLayout* aLayout)
+	{
+	for(TInt k = 0; aLayout && k < aLayout->Count(); ++k)
+		{
+		CHuiCanvasVisual* canvasVisual = dynamic_cast<CHuiCanvasVisual*>(&(aLayout->Visual(k)));
+
+		if (canvasVisual)
+			{
+			if (canvasVisual->ExternalContent() == aExternalContentVisual)
+				{
+				// Remove aExternalContentVisual from the parent visual
+				canvasVisual->SetExternalContentL(NULL);
+				}
+			}
+		else
+			{
+			CHuiLayout* layoutVisual = dynamic_cast<CHuiLayout*>(&(aLayout->Visual(k)));
+			if ( layoutVisual)
+				{
+				RemoveExternalContentVisualFromParentL(aExternalContentVisual,layoutVisual);
+				}
+			}
+		}
+	}
+
+
+void CHuiRosterImpl::FreezeVisibleContentL(TBool aEnable)
+    {
+    if (aEnable)
+        {    
+        if (!iCanvasGc)
+            {
+            CHuiRenderPlugin& renderplugin = CHuiStatic::Renderer();
+            iCanvasGc = renderplugin.CreateCanvasGcL();
+            }    
+        if (!iCanvasRenderBuffer)
+            {
+            iCanvasRenderBuffer = iCanvasGc->CreateRenderBufferL(TSize(0,0));
+            iCanvasRenderBuffer->InitializeL(CHuiStatic::Env().Display(0).VisibleArea().Size());
+            iCanvasRenderBuffer->Copy(TPoint(0,0));    
+            iCanvasRenderBufferOrientation = CHuiStatic::Env().Display(0).Orientation();
+            }
+        }
+    else
+        {
+        delete iCanvasGc;
+        iCanvasGc = NULL;        
+        delete iCanvasRenderBuffer;
+        iCanvasRenderBuffer = NULL;
+        SetChanged();
+        }    
+    }
+
+TBool CHuiRosterImpl::IsVisibleContentFrozen() const
+    {
+    return ((iCanvasRenderBuffer != NULL) && (iCanvasGc != NULL));
+    }
+    
+void CHuiRosterImpl::EffectSetEffect(CHuiFxEffect* aEffect)
+    {
+    if (iEffect)
+        {
+        delete iEffect;
+        iEffect = NULL;
+        }
+    iEffect = aEffect;
+    SetChanged();
+    }
+
+TReal32 CHuiRosterImpl::EffectOpacityTarget() const
+    {
+    return iEffectOpacity; 
+    }
+
+void CHuiRosterImpl::EffectSetOpacity(TReal32 aOpacity)
+    {
+    iEffectOpacity = aOpacity;
+    }
+
+void CHuiRosterImpl::EffectDrawSelf( CHuiGc &aGc, const TRect & aDisplayRect) const
+    {
+    DrawSelf(aGc, iDisplay);
+    }
+
+THuiRealRect CHuiRosterImpl::EffectDisplayRect() const __SOFTFP
+    {
+    if (iDisplay)
+        {
+        return iDisplay->VisibleArea();
+        }
+    else
+        {
+        return THuiRealRect(TRect(0,0,0,0));
+        }    
+    }
+
+MHuiEffectable* CHuiRosterImpl::Effectable()
+    {
+    return this;
+    }
+
+void CHuiRosterImpl::SetLoadingEffect(TBool /*aLoading*/)
+    {
+    // not needed
+    }
+void CHuiRosterImpl::EffectSetSource( TBool aIsInput1 )
+    {
+    iIsInput1 = aIsInput1;
+    }
+
+TBool CHuiRosterImpl::EffectGetSource() const
+    {
+    return iIsInput1;
+    }