uiacceltk/hitchcock/Client/src/alfcontrol.cpp
changeset 0 15bf7259bb7c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/uiacceltk/hitchcock/Client/src/alfcontrol.cpp	Tue Feb 02 07:56:43 2010 +0200
@@ -0,0 +1,1149 @@
+/*
+* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:   Control base class.
+*
+*/
+
+
+
+#include "alf/alfcontrol.h"
+#include "alf/alfcontrolgroup.h"
+#include "alf/alfdisplay.h"
+#include "alf/alfroster.h"
+#include "alf/alfenv.h"
+#include "alf/alfvisualfactory.h"
+#include "alfclient.h"
+#include "alf/alfgencomponent.h"
+#include "alf/alfconstants.h"
+#include "alf/alftimedvalue.h"
+#include "alflogger.h"
+
+#include <uiacceltk/HuiUtil.h>
+
+#include <eikappui.h>
+
+// Private structure
+struct CAlfControl::TPrivateData
+    {
+    CAlfEnv* iEnv;                      // Not owned.
+    CAlfControlGroup* iOwnerGroup;      // Not owned.
+    CAlfDisplay* iBoundDisplay;         // Not owned.
+    TInt iId;                           // Owned.
+    TInt iHostId;                       // Owned.
+    TInt iRole;                         // Owned.
+    RPointerArray<CAlfVisual> iVisuals; // Not owned.
+    CAlfControl* iHost;                 // Not owned.
+    struct SConnection
+        {
+        CAlfControl* iControl;          // Not owned.
+        TInt iRole;                     // Owned.
+        };
+    RArray<SConnection> iConnections;   // Owned.
+    TBool iFocusing;                    // Owned.
+    TBool iHasFocus;                    // Owned.
+    CAlfGenComponent* iComms;           // Owned
+    };
+
+
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// Constructor
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CAlfControl::CAlfControl()
+    {
+    }
+
+// ---------------------------------------------------------------------------
+// ConstructL
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CAlfControl::ConstructL(CAlfEnv& aEnv)
+    {
+    iData = new (ELeave) TPrivateData;
+    
+    iData->iEnv = &aEnv;
+    iData->iFocusing = EFalse;
+    //iData->iId = CAlfStatic::GenerateId();  
+        
+    // NULL data
+    iData->iOwnerGroup = NULL;
+    iData->iBoundDisplay = NULL;
+    iData->iId = 0;
+    iData->iHostId = 0;
+    iData->iRole = 0;
+    iData->iVisuals.Reset();
+    iData->iHost = NULL;
+    iData->iConnections.Reset();
+    iData->iHasFocus = EFalse;
+    iData->iComms = 0;
+    iData->iComms = CAlfGenComponent::NewL(aEnv,
+            EAlfCntrlCreate, 
+            0, 
+            KNullDesC8);
+
+    iData->iId = Identifier(); // to have unique value 
+    }
+
+// ---------------------------------------------------------------------------
+// Destructor.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CAlfControl::~CAlfControl()
+    {
+    if ( iData )
+        { 
+        // Cancel scheduled commands for this control.
+        Env().CancelCustomCommands(this);
+        Env().CancelCommands(this);
+
+        if(iData->iHost)
+            {
+            iData->iHost->RemoveConnection(this);
+            iData->iHost = NULL;
+            }
+
+        for(TInt i = iData->iConnections.Count() - 1; i >= 0; --i)
+            {
+            RemoveConnection(iData->iConnections[i].iControl);
+            }
+        iData->iConnections.Reset();
+
+        // The visuals are owned by the control.
+        iData->iVisuals.ResetAndDestroy();
+        delete iData->iComms;
+        }
+    delete iData;
+    iData = NULL;
+    }
+
+// ---------------------------------------------------------------------------
+// Returns server handle
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CAlfControl::Identifier() const
+    {
+    return iData->iComms->Identifier();
+    }
+
+// ---------------------------------------------------------------------------
+// Returns the env
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CAlfEnv& CAlfControl::Env() const
+    {
+    return *iData->iEnv;
+    }
+
+
+// ---------------------------------------------------------------------------
+// Returns control group that this control is in.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CAlfControlGroup* CAlfControl::ControlGroup() const
+    {
+    return iData->iOwnerGroup;
+    }
+    
+// ---------------------------------------------------------------------------
+// Sets the control group
+// ---------------------------------------------------------------------------
+//   
+void CAlfControl::SetControlGroup(CAlfControlGroup& aOwnerGroup)
+    {
+    iData->iOwnerGroup = &aOwnerGroup;
+    }
+    
+// ---------------------------------------------------------------------------
+// Returns bound display
+// ---------------------------------------------------------------------------
+//     
+EXPORT_C CAlfDisplay* CAlfControl::Display() const
+    {
+    return iData->iBoundDisplay;
+    }
+    
+// ---------------------------------------------------------------------------
+// Sets bound display
+// ---------------------------------------------------------------------------
+//   
+EXPORT_C void CAlfControl::BindDisplay(CAlfDisplay& aDisplay)
+    {
+    iData->iBoundDisplay = &aDisplay;
+    }    
+
+// ---------------------------------------------------------------------------
+// Sets control ID.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CAlfControl::SetId(TInt aId)
+    {
+    iData->iId = aId;
+    }
+
+// ---------------------------------------------------------------------------
+// Returns control ID.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CAlfControl::Id() const
+    {
+    return iData->iId;
+    }
+
+// ---------------------------------------------------------------------------
+// Appends new visual
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CAlfControl::Append(CAlfVisual* aVisual, CAlfLayout* aParentLayout)
+    {
+    TInt err = KErrNone;
+    
+    ASSERT(aVisual); // must not be null
+    
+    if(&aVisual->Owner() != this) // ownership cannot be altered here
+        {
+        return KErrNotSupported;
+        }
+    
+    // prevent adding visual several times
+    for (TInt i = iData->iVisuals.Count()-1;i>=0;i--)
+        {
+        if (iData->iVisuals[i] == aVisual)
+            {
+            return KErrAlreadyExists;
+            }
+        }
+
+    // Append the visual to the visuals array.
+    err = iData->iVisuals.Append(aVisual);
+    if ( err )
+        {
+        __ALFLOGSTRING1( "CAlfControl::Append return error %d", err )
+        return err;
+        }
+
+    if(aParentLayout)
+        { // once parent layout has been set, the visual has already relation in shape 
+          // server side, tell the layout that theres no need to synch that info to server 
+          // anymore (latter param)
+        err = aParentLayout->Append(aVisual, ETrue);  
+        if ( err != KErrNone )
+            {
+            __ALFLOGSTRING1( "CAlfControl::Append return error %d", err )
+            // Do cleanup
+            iData->iVisuals.Remove(iData->iVisuals.Find(aVisual));
+            return err;
+            }
+        }
+     /*   
+    if ( iData->iInformServerAboutAppendRemove )
+        {
+        TInt2 params(aVisual->Identifier(), aParentLayout ? aParentLayout ->Identifier() : 0 );
+        TPckgC<TInt2> inPckg(params);
+        TBuf8<1> dum;
+        TInt err = iData->iComms->DoSynchronousCmd( EAlfCntrlAppendVisual, inPckg , dum );
+        if ( err != KErrNone )
+            {
+            __ALFLOGSTRING1( "CAlfControl::Append return error %d", err )
+            // Do cleanup
+            if ( aParentLayout )
+                {
+                aParentLayout->Remove(aVisual);  
+                }
+            iData->iVisuals.Remove(iData->iVisuals.Find(aVisual));
+            return err;
+            }
+        }*/
+
+    TRAP(err, VisualAddedL(aVisual));
+    if ( err != KErrNone )
+        {
+        __ALFLOGSTRING1( "CAlfControl::Append return error %d", err )
+        // Do cleanup
+        if ( aParentLayout )
+            {
+            aParentLayout->Remove(aVisual);
+            }
+        Remove( aVisual );
+        }
+    return err;
+    }
+
+// ---------------------------------------------------------------------------
+// Removes visual
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CAlfControl::Remove(CAlfVisual* aVisual)
+    {
+    /*
+    if ( iData->iInformServerAboutAppendRemove && aVisual)
+        {
+        TPckgC<TInt> inPckg(aVisual->Identifier());
+        TBuf8<1> dum;
+        iData->iComms->DoSynchronousCmd( EAlfCntrlRemoveVisual, inPckg , dum );
+        }*/
+    
+    TInt index = iData->iVisuals.Find(aVisual);
+    if(index != KErrNotFound)
+        {
+        VisualRemoved(aVisual);
+        iData->iVisuals.Remove(index);
+        }
+    }
+
+// --------------------------------------------------------------------------
+// Creates and appends new visual
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CAlfVisual* CAlfControl::AppendVisualL(TAlfVisualType aVisualType,
+                                                CAlfLayout* aParentLayout,
+                                                TInt aImplementationUid )
+    {
+    CAlfVisual* visual = AlfVisualFactory::NewVisualLC(aVisualType, 
+                                        aParentLayout, *this, *iData->iEnv, aImplementationUid);
+                                                             
+    TInt err = Append(visual, aParentLayout);
+    User::LeaveIfError( err );
+    CleanupStack::Pop(visual);
+    return visual;
+    }
+
+// ---------------------------------------------------------------------------
+// Creates and appends new layout
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CAlfLayout* CAlfControl::AppendLayoutL(TAlfLayoutType aLayoutType,
+                                                CAlfLayout* aParentLayout,
+                                                TInt aImplementationUid)
+    {
+    CAlfLayout* layout = AlfVisualFactory::NewLayoutLC(aLayoutType,
+                        aParentLayout, *this, *iData->iEnv, aImplementationUid);
+     
+    TInt err = Append(layout, aParentLayout);
+    User::LeaveIfError( err );
+    CleanupStack::Pop(layout);
+    return layout;
+    }
+
+// ---------------------------------------------------------------------------
+// Returns indexed visual
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CAlfVisual& CAlfControl::Visual(TInt aIndex) const
+    {
+    return *iData->iVisuals[aIndex];
+    }
+
+// ---------------------------------------------------------------------------
+// Returns visual count.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CAlfControl::VisualCount() const
+    {
+    return iData->iVisuals.Count();
+    }
+
+// ---------------------------------------------------------------------------
+// Finds visual with given tag.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CAlfVisual* CAlfControl::FindTag(const TDesC8& aTag) const
+    {
+    ASSERT(iData);
+
+    for(TInt i = 0; i < iData->iVisuals.Count(); ++i)
+        {
+        if(iData->iVisuals[i]->TagMatches(aTag))
+            {
+            return iData->iVisuals[i];
+            }
+        }   
+        
+    return NULL;
+    }
+
+
+// ---------------------------------------------------------------------------
+// Returns host.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CAlfControl* CAlfControl::Host() const
+    {
+    return iData->iHost;
+    }
+
+// ---------------------------------------------------------------------------
+// Sets host.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CAlfControl::SetHost(CAlfControl* aHost)
+    {
+    // do not call this function directly. This should be only called by the 
+    // AddConnectionL and RemoveConnection functions.
+    
+    if ( aHost )
+        {    
+        // When adding a host, the host must be aware of this connection first.
+        __ASSERT_ALWAYS( aHost->FindConnection(this) != KErrNotFound, USER_INVARIANT() );
+        }
+    
+    TRAPD(err, HostChangingL(aHost));
+    if(err != KErrNone)
+        {
+        if(aHost)
+            {
+            RemoveVisualsFromHostControl(*aHost);
+            }
+        return;
+        }
+
+    iData->iHost = aHost;
+    }
+
+// ---------------------------------------------------------------------------
+// Adds control connection.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CAlfControl::AddConnectionL(CAlfControl* aConnectedControl, TInt aRole)
+    {
+    // check that the connection does not exist:
+    if ( FindConnection( aConnectedControl ) != KErrNotFound )
+        {
+        User::Leave( KErrAlreadyExists );
+        }
+    
+    TPrivateData::SConnection client;
+    client.iControl = aConnectedControl;
+    client.iRole = aRole;
+    User::LeaveIfError(iData->iConnections.Append(client));
+
+    // This control is now the client's host.
+    aConnectedControl->SetHost(this);
+
+    ConnectionAddedL(aConnectedControl, aRole);
+    }
+
+// ---------------------------------------------------------------------------
+// Removes control connection
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CAlfControl::RemoveConnection(CAlfControl* aConnectedControl)
+    {
+    for(TInt i = 0; i < iData->iConnections.Count(); ++i)
+        {
+        if(iData->iConnections[i].iControl == aConnectedControl)
+            {
+            aConnectedControl->SetHost(NULL);
+            const TInt role = iData->iConnections[i].iRole;
+            iData->iConnections.Remove(i);
+            
+            ConnectionRemoved(aConnectedControl, role);
+            return;
+            }
+        }
+    // The client must exist.
+    USER_INVARIANT();
+    }
+
+// ---------------------------------------------------------------------------
+// Returns connection count
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CAlfControl::ConnectionCount() const
+    {
+    return iData->iConnections.Count();
+    }
+
+// ---------------------------------------------------------------------------
+// Returns indexed connection.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CAlfControl& CAlfControl::Connection(TInt aIndex) const
+    {
+    return *iData->iConnections[aIndex].iControl;
+    }
+
+// ---------------------------------------------------------------------------
+// Returns ordinal-indexed connection.
+// @deprecated
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CAlfControl& CAlfControl::ConnectionByOrdinal(TInt aOrdinal) const
+    {
+    // First look based on role.
+    for(TInt i = 0; i < iData->iConnections.Count(); ++i)
+        {
+        if(iData->iConnections[i].iRole == aOrdinal + 1)
+            {
+            return *iData->iConnections[i].iControl;
+            }
+        }
+
+    // Fall back to index.
+    return Connection(aOrdinal);
+    }
+
+// ---------------------------------------------------------------------------
+// Returns given connection index.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CAlfControl::FindConnection(const CAlfControl* aConnected) const
+    {
+    for(TInt i = 0; i < iData->iConnections.Count(); ++i)
+        {
+        if(iData->iConnections[i].iControl == aConnected)
+            {
+            return i;
+            }
+        }
+    return KErrNotFound;
+    }
+
+// ---------------------------------------------------------------------------
+// Returns connection role
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CAlfControl::ConnectionRole(TInt aIndex) const
+    {
+    return iData->iConnections[aIndex].iRole;
+    }
+
+// ---------------------------------------------------------------------------
+// Returns connection ordinal
+// @deprecated
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CAlfControl::ConnectionOrdinal(TInt aIndex) const
+    {
+    if(iData->iConnections[aIndex].iRole)
+        {
+        return iData->iConnections[aIndex].iRole - 1;
+        }
+    return aIndex;
+    }
+
+// ---------------------------------------------------------------------------
+// Returns role
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CAlfControl::Role() const
+    {
+    /*if(iHost)
+        {
+        return iHost->ClientRole(iHost->FindClient(this));
+        }
+    // Zero is the default role.
+    return 0;*/
+    return iData->iRole;
+    }
+
+// ---------------------------------------------------------------------------
+// Sets role
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CAlfControl::SetRole(TInt aRole)
+    {
+    iData->iRole = aRole;
+    }
+
+// ---------------------------------------------------------------------------
+// Returns host ID.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CAlfControl::HostId() const
+    {
+    return iData->iHostId;
+    }
+
+// ---------------------------------------------------------------------------
+// Sets host ID
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CAlfControl::SetHostId(TInt aHostId)
+    {
+    // If adding automatic visual host, there cannot be already one defined.
+    __ASSERT_ALWAYS( !iData->iHost, USER_INVARIANT() );
+    
+    iData->iHostId = aHostId;
+    }
+
+// ---------------------------------------------------------------------------
+// Returns container layout if set.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CAlfLayout* CAlfControl::ContainerLayout(const CAlfControl* /*aConnected*/) const
+    {
+    // Generic controls aren't able to provide container layouts.
+    return NULL;
+    }
+
+// ---------------------------------------------------------------------------
+// Called when new visual is added.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CAlfControl::VisualAddedL(CAlfVisual* aVisual)
+    {
+    // Add the new visual to the container layout.
+    if(iData->iHost && !aVisual->Layout())
+        {
+        CAlfLayout* container = iData->iHost->ContainerLayout(this);
+        if(container)
+            {
+            User::LeaveIfError( container->Append(aVisual) );
+            }
+        }
+    else
+        {
+        // @todo Calling ShowVisualL panics the server, becuase it has
+        // been called already on the construction.
+        /*
+        // If the control has been bound to a display (for example, when
+        // the control is shown), new visuals will be automatically shown.
+        if( iData->iBoundDisplay && 
+                (iData->iOwnerGroup && 
+                 iData->iBoundDisplay->Roster().Find(
+                    *iData->iOwnerGroup) != KErrNotFound) && 
+           !aVisual->Layout() && !aVisual->Display())
+            {
+            iData->iBoundDisplay->Roster().ShowVisualL(*aVisual);
+            }
+            */
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// Called when visual is removed.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CAlfControl::VisualRemoved(CAlfVisual* aVisual)
+    {
+    // Add the new visual to the container layout.
+    if(iData->iHost)
+        {
+        CAlfLayout* container = iData->iHost->ContainerLayout(this);
+        if(container && aVisual->Layout() == container )
+            {
+            container->Remove(aVisual);
+            }
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// Called when connection is added.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CAlfControl::ConnectionAddedL(CAlfControl* /*aConnectedControl*/, TInt /*aRole*/)
+    {
+    // Do nothing.
+    }
+
+// ---------------------------------------------------------------------------
+// Called when connection is removed.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CAlfControl::ConnectionRemoved(CAlfControl* /*aConnectedControl*/, TInt /*aRole*/)
+    {
+    // Do nothing.
+    }
+
+// ---------------------------------------------------------------------------
+// Removes visual from layout.
+// ---------------------------------------------------------------------------
+//
+void CAlfControl::RemoveVisualsFromHostControl( CAlfControl& aHostControl )
+    {
+    __ASSERT_ALWAYS( &aHostControl != this, USER_INVARIANT() );
+    
+    // Remove the visuals.
+    for(TInt i = 0; i < iData->iVisuals.Count(); ++i)
+        {
+        if ( iData->iVisuals[i]->Layout() && &iData->iVisuals[i]->Layout()->Owner() == &aHostControl )
+            {
+            iData->iVisuals[i]->Layout()->Remove(iData->iVisuals[i]);
+            
+            // If the own control group is showing still in some roster,
+            // we need to add the root visuals over there
+            /* // do we need this?
+            if ( iBoundDisplay )
+                {
+                TRAP_IGNORE( iBoundDisplay->Roster().ShowVisualL( iVisuals[i] ) );
+                }*/
+            }
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// Called when the host is about to change
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CAlfControl::HostChangingL(CAlfControl* aNewHost)
+    {
+    CAlfLayout* newContainer = 0;
+    TInt i = 0;
+
+    if(aNewHost)
+        {
+        // The container layout provided by the new host.
+        newContainer = aNewHost->ContainerLayout(this);
+        }
+
+    if(iData->iHost)
+        {
+        // There is a previous host.
+        // Remove the visuals.
+        RemoveVisualsFromHostControl(*iData->iHost);
+        }
+
+    if(newContainer)
+        {
+        for(i = 0; i < iData->iVisuals.Count(); ++i)
+            {
+            // Only the visuals that aren't already attached to a layout
+            // are added to the container layout.
+            if(!iData->iVisuals[i]->Layout())
+                {
+                User::LeaveIfError( newContainer->Append(iData->iVisuals[i]) );
+                }
+            }
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// Shows conttol on the given display
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CAlfControl::ShowL(CAlfDisplay& aDisplay)
+    {
+    if(HostId())
+        {
+        CAlfControl* host = Env().FindControl(HostId());
+
+        if(host)
+            {
+            host->AddConnectionL(this, Role());
+            }
+        else
+            {
+            /** @todo Leave? */
+            }
+        }
+
+    BindDisplay(aDisplay);
+
+    // @todo: do we need this? the roster::show is already passed
+    // to the server side, which call the same thing.
+    
+    // Show all the visuals on the specified display.
+    for(TInt i = 0; i < iData->iVisuals.Count(); ++i)
+        {
+
+        // Set the display of the root visual
+        if( !iData->iVisuals[i]->Layout() )
+            {
+            iData->iVisuals[i]->SetDisplay( &aDisplay );
+            }
+        }
+        
+    NotifyControlVisibility(ETrue, aDisplay);
+    }
+
+// ---------------------------------------------------------------------------
+// Hides control from the given display
+// ---------------------------------------------------------------------------
+//
+void CAlfControl::Hide(CAlfDisplay& aDisplay)
+    {
+    NotifyControlVisibility(EFalse, aDisplay);
+    
+    // Hide all the visuals on the specified display.
+    for(TInt i = 0; i < iData->iVisuals.Count(); ++i)
+        {
+        // The visuals that are part of a layout will be shown when the
+        // layout is shown.
+        if(!iData->iVisuals[i]->Layout() && iData->iVisuals[i]->Display() == &aDisplay)
+            {
+            aDisplay.Roster().HideVisual(*iData->iVisuals[i]);
+            }
+        }
+
+    // Relinquish focus on this display
+    CAlfRoster& roster = aDisplay.Roster();
+    if ( roster.FocusedControl() == this )
+        {
+        roster.ClearFocus();
+        }
+    
+    // Unbind from display?
+    if(iData->iBoundDisplay == &aDisplay)
+        {
+        iData->iBoundDisplay = NULL;
+        }
+
+    // Unlink from parent control.
+    if(Host() && HostId() )
+        {
+        Host()->RemoveConnection(this);
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// Called when visibility changes.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CAlfControl::NotifyControlVisibility(TBool /*aIsVisible*/, 
+                                                   CAlfDisplay& /*aDisplay*/)
+    {
+    // Nothing to do by default.
+    }
+
+// ---------------------------------------------------------------------------
+// Converts point from relative to absolute coordinates
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TPoint CAlfControl::HostToDisplay(const TPoint& aPoint) const
+    {
+    if(!iData->iHost)
+        {
+        return aPoint;
+        }
+
+    CAlfLayout* container = iData->iHost->ContainerLayout(this);
+
+    return container->LocalToDisplay(aPoint) + container->Pos().Target();
+    }
+
+// ---------------------------------------------------------------------------
+// Converts point from absolute to relative coordinates
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TPoint CAlfControl::DisplayToHost(const TPoint& aPoint) const
+    {
+    if(!iData->iHost)
+        {
+        return aPoint;
+        }
+
+    CAlfLayout* container = iData->iHost->ContainerLayout(this);
+
+    return container->DisplayToLocal(aPoint) - container->Pos().Target();
+    }
+
+// ---------------------------------------------------------------------------
+// Returns bounding rect.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TRect CAlfControl::Bounds() const
+    {
+    TPoint min;
+    TPoint max;
+
+    min.iX = KMaxTInt;
+    min.iY = KMaxTInt;
+    max.iX = KMinTInt;
+    max.iY = KMinTInt;
+
+    for(TInt i = 0; i < iData->iVisuals.Count(); ++i)
+        {
+        TRect visualRect = iData->iVisuals[i]->DisplayRectTarget();
+
+        min.iX = Min(min.iX, visualRect.iTl.iX);
+        min.iY = Min(min.iY, visualRect.iTl.iY);
+        max.iX = Max(max.iX, visualRect.iBr.iX);
+        max.iY = Max(max.iY, visualRect.iBr.iY);
+        }
+
+    return TRect(min, max);
+    }
+
+// ---------------------------------------------------------------------------
+// Is the given point inside the control area?
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TBool CAlfControl::HitTest(const TPoint& aPoint) const
+    {
+    return Bounds().Contains(aPoint);
+    }
+
+    
+// ---------------------------------------------------------------------------
+// Tries to get the focus.
+// ---------------------------------------------------------------------------
+//    
+EXPORT_C void CAlfControl::AcquireFocus()
+    {
+    if ( !AcceptInput() ) // Cannot take focus to this control
+        {
+        return;
+        }
+
+    // Focus is set set separately in each display the control has visuals in.
+    // Find all the displays
+    RPointerArray<CAlfDisplay> displays;
+    for(TInt i = 0; i < iData->iVisuals.Count(); ++i)
+        {
+        if(iData->iVisuals[i]->Display())
+            {
+            // Do not allow duplicates. Ignore error.
+            (void)displays.InsertInAddressOrder( iData->iVisuals[i]->Display() );
+            }
+        }
+    
+    // go through the displays
+    for ( TInt d = 0 ; d < displays.Count() ; d++ )
+        {
+        if ( displays[d]->Roster().FocusedControl() != this )
+            {
+            displays[d]->Roster().SetFocus(*this );
+            }
+        }
+    
+    displays.Close();
+    }   
+
+// ---------------------------------------------------------------------------
+// Attempt to remove the focus from this control
+// ---------------------------------------------------------------------------
+//    
+EXPORT_C void CAlfControl::RelinquishFocus()
+    {
+    // Focus needs to be removed from all displays that the control has visuals in
+    for(TInt i = 0; i < iData->iVisuals.Count(); ++i)
+        {
+        if(iData->iVisuals[i]->Display())
+            {
+            // This method should have no effect on rosters where this does not match the currently focused control
+            CAlfRoster& roster = iData->iVisuals[i]->Display()->Roster();
+            if ( roster.FocusedControl() == this )
+                {
+                roster.ClearFocus(); // Potentially called repeatedly for each visual. Optimization is in CAlfRoster
+                }
+            }
+        }
+    }   
+// ---------------------------------------------------------------------------
+// Does this control have focus?
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TBool CAlfControl::Focus() const
+    {
+    return iData->iHasFocus;
+    }
+
+// ---------------------------------------------------------------------------
+// Is one of the child focused?
+// ---------------------------------------------------------------------------
+//   
+EXPORT_C CAlfControl* CAlfControl::FocusedConnection() const
+    {
+    CAlfControl* focusChild = NULL;
+    
+    const TInt connectionCount = ConnectionCount();
+    for ( TInt c = 0 ; c < connectionCount && !focusChild ; c++ )
+        {
+        CAlfControl& childConnection =  Connection(c);
+        if ( childConnection.Focus() || childConnection.FocusedConnection() )
+            {
+            focusChild = &childConnection;
+            }
+        }
+        
+    return focusChild;
+    }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//      
+void CAlfControl::FocusChainChanged( TBool aInFocusChain )
+    {
+    TAny* pInFocusChain = &aInFocusChain;
+    PropertyOwnerExtension( KUidAlfPropOwnerExtControlFocusChainChanged, &pInFocusChain );
+    }
+
+// ---------------------------------------------------------------------------
+// Sets focus
+// ---------------------------------------------------------------------------
+//
+void CAlfControl::SetFocus(CAlfDisplay& aDisplay, TBool aHasFocus)
+    {
+    if ( ( iData->iHasFocus && !aHasFocus ) || 
+         ( !iData->iHasFocus && aHasFocus ) )
+        {
+        iData->iHasFocus = aHasFocus;
+        FocusChanged(aDisplay, aHasFocus);
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// Is focusing control?
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TBool CAlfControl::IsFocusing() const
+    {
+    return iData->iFocusing;
+    }
+
+// ---------------------------------------------------------------------------
+// Set is focusing control.
+// ---------------------------------------------------------------------------
+//
+void CAlfControl::SetFocusing(TBool aFocusing)
+    {
+    iData->iFocusing = aFocusing;
+    }
+
+// ---------------------------------------------------------------------------
+// Called when focus changes.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CAlfControl::FocusChanged(CAlfDisplay& /*aDisplay*/, TBool /*aFocused*/)
+    {
+    // Do nothing by default.
+    }
+
+// ---------------------------------------------------------------------------
+// Does control group accept input?
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TBool CAlfControl::AcceptInput() const
+    {
+    if(iData->iOwnerGroup)
+        {
+        return iData->iOwnerGroup->AcceptInput();
+        }
+    return ETrue;    
+    }
+
+
+// ---------------------------------------------------------------------------
+// Called when event is received.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TBool CAlfControl::OfferEventL(const TAlfEvent& /*aEvent*/)
+    {
+    return EFalse;
+    }
+
+// ---------------------------------------------------------------------------
+// Returns control area.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TRect CAlfControl::DisplayArea() const
+    {
+    if(iData->iBoundDisplay)
+        {
+        return iData->iBoundDisplay->VisibleArea();
+        }
+    
+    // The first visual shown on a display determines the display area.            
+    for(TInt i = 0; i < iData->iVisuals.Count(); ++i)
+        {
+        if(iData->iVisuals[i]->Display())
+            {
+            return iData->iVisuals[i]->Display()->VisibleArea();
+            }
+        }
+        
+    if(!Env().DisplayCount())
+        {
+        // No displays created in the environment yet. Assume device 
+        // native resolution.
+        //return TRect(TPoint(0, 0), AlfUtil::ScreenSize());
+        CCoeEnv* coe = CCoeEnv::Static();
+        if ( coe )
+            {
+            return static_cast<CEikAppUi*>(coe->AppUi())->ClientRect(); 
+            }
+        else
+            {
+            return TRect( 0,0,0,0 );
+            }
+        }
+        
+    // Assume it is the primary display, then.   
+    return Env().PrimaryDisplay().VisibleArea();
+    }
+
+// ---------------------------------------------------------------------------
+// Returns the center point of the area.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TAlfRealPoint CAlfControl::DisplayCenter() const
+    {
+    TRect area(DisplayArea());
+    return area.iTl + TAlfRealPoint(area.Width()/2.f, area.Height()/2.f);
+    }
+
+// ---------------------------------------------------------------------------
+// Cancels all commands
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CAlfControl::CancelAllCommands()
+    {
+    iData->iEnv->CancelCustomCommands(this);
+    iData->iEnv->CancelCommands(this);
+    
+    for(TInt i = 0; i < iData->iVisuals.Count(); ++i)
+        {
+        iData->iEnv->CancelCommands(iData->iVisuals[i]);
+        }
+    }
+    
+// ---------------------------------------------------------------------------
+// Clear flag.
+// ---------------------------------------------------------------------------
+//
+void CAlfControl::ClearChanged()
+    { // todo: does client need to access this information
+    }
+
+// ---------------------------------------------------------------------------
+// Called when layout changes.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CAlfControl::VisualDestroyed(CAlfVisual& aVisual)
+    {
+    // If called from CAlfVisual::RemoveAndDestroyAllD the server
+    // side object is removed also automatically. Otherwise not..
+    Remove(&aVisual);
+    }
+
+// ---------------------------------------------------------------------------
+// Called when visual layout is updated (see visual flags)
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CAlfControl::VisualLayoutUpdated(CAlfVisual& /*aVisual*/)
+    {
+    
+    }
+  
+// ---------------------------------------------------------------------------
+// Called when draw preparation failed (not implemented currenltly)
+// ---------------------------------------------------------------------------
+// 
+EXPORT_C void CAlfControl::VisualPrepareDrawFailed(CAlfVisual& /*aVisual*/, TInt /*aErrorCode*/)
+    {
+    
+    }
+
+// ---------------------------------------------------------------------------
+//  future proofing  
+// ---------------------------------------------------------------------------
+//  
+EXPORT_C void CAlfControl::PropertyOwnerExtension(const TUid& aExtensionUid, TAny** aExtensionParams)
+    {
+    CAlfPropertyOwner::PropertyOwnerExtension(aExtensionUid, aExtensionParams);
+    }
+