uiacceltk/hitchcock/ServerCore/Src/alfnodes.cpp
changeset 0 15bf7259bb7c
child 3 d8a3531bc6b8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/uiacceltk/hitchcock/ServerCore/Src/alfnodes.cpp	Tue Feb 02 07:56:43 2010 +0200
@@ -0,0 +1,2162 @@
+/*
+* Copyright (c) 2008 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:   ?Description
+*
+*/
+
+#include <uiacceltk/HuiCanvasVisual.h>
+#include <alfwindowstructs.h>
+
+#include "huiwscanvascommands.h"
+#include "alfnodes.h"
+#include "alfhierarchymodel.h"
+#include "alfstreamerserver.h"
+#include "alfwindowmanager.h"
+#include "alfwindow.h"
+#include "alfwindowdata.h"
+
+#ifdef ALF_DEBUG_PRINT_NODE_INFO
+    #define _ALF_LOGGING
+    #include "alflogger.h"
+    #undef _ALF_LOGGING
+#else
+    #include "alflogger.h"
+#endif
+// ---------------------------------------------------------------------------
+// Constructor
+// ---------------------------------------------------------------------------
+//
+CAlfNode::CAlfNode( ) :  
+    iVisible( ETrue )
+    {
+    }
+
+// ---------------------------------------------------------------------------
+// ConstructL
+// ---------------------------------------------------------------------------
+//
+void CAlfNode::ConstructL( CAlfHierarchyModel* aModel, RMemReadStream* aStream  )
+    {
+    iModel = aModel;
+    iId = aStream->ReadInt32L();
+    }
+
+void CAlfNode::SetTracking( TBool aValue )
+    {
+    iTrackNode = aValue;
+    if ( iWindow )
+        {
+        iWindow->SetNodeTracking( aValue );
+        }
+    }
+// ---------------------------------------------------------------------------
+// OrphonMe
+// ---------------------------------------------------------------------------
+//
+CAlfNode* CAlfNode::OrphonMe()
+    {
+    __ALFLOGSTRING1("CAlfNode::OrphonMe %d", iId);
+	// this window will not be used anymore by wserv and cannot be drawn into. Thus destroying the
+	// visual representing this node is safe.
+    if ( iWindow && iModel )
+        {
+        iModel->Server().WindowMgr()->DestroyWindow( *iWindow );
+        iWindow = NULL;
+        }
+
+    CAlfNode* sibling = iSibling;
+    iSibling = NULL;
+    iParent = NULL;
+    return sibling;
+    }
+
+// ---------------------------------------------------------------------------
+// ResolveParentL
+// ---------------------------------------------------------------------------
+//
+void CAlfNode::ResolveParent( TUint32 aParentId, TInt aMyId )
+    {
+    CAlfNode* tmp = iModel->FindNode( aParentId );
+    if ( tmp )
+        {
+        // 1. set parent, if there is one (root node is the only exception )
+        iParent = tmp;
+        // Possible sprite, textcursor, anim and child windows have different lists on the node
+        switch( iType )
+            {
+            default:
+                {
+                SetFirstChild();
+                break;
+                }
+            case MWsWindowTreeNode::EWinTreeNodeAnim:
+                {
+                SetFirstAnim();
+                break;
+                }
+            case MWsWindowTreeNode::EWinTreeNodeSprite:
+                {
+                SetFirstSprite();
+                break;
+                }
+            case MWsWindowTreeNode::EWinTreeNodeStandardTextCursor:
+                {
+                ASSERT( !iParent->iTextCursor );
+                __ALFLOGSTRING1("parent->iTextCursor %d", iParent->iTextCursor );
+                iParent->iTextCursor = (CAlfNodeTextCursor*)this;
+                __ALFLOGSTRING1("parent->iTextCursor %d", iParent->iTextCursor );
+                break;
+                }
+            }
+        } 
+    iId = aMyId;
+    iModel->InsertNode( iId, this );
+    ASSERT( iParent != NULL || iType == MWsWindowTreeNode::EWinTreeNodeRoot);
+    
+    if ( iType == MWsWindowTreeNode::EWinTreeNodeGroup )
+        {
+        iGroupId = iId;
+        }
+    else
+        {
+        iGroupId = FindParentGroup();
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// SetFirstChild
+// ---------------------------------------------------------------------------
+//
+void CAlfNode::SetFirstChild()
+    {
+    if ( iParent->iChild )
+        {
+        // pass over the previous first child and make it my sibling
+        iSibling = iParent->iChild;
+        }
+    // jealously make me the first child
+    iParent->iChild = this;
+    }
+// ---------------------------------------------------------------------------
+// SetFirstChild
+// ---------------------------------------------------------------------------
+//
+void CAlfNode::SetFirstAnim()
+    {
+    if ( iParent->iAnimChild )
+        {
+        // pass over the previous first child and make it my sibling
+        iSibling = iParent->iAnimChild;
+        }
+    // jealously make me the first child
+    iParent->iAnimChild = (CAlfNodeAnim*)this;
+    }
+
+// ---------------------------------------------------------------------------
+// SetFirstChild
+// ---------------------------------------------------------------------------
+//
+void CAlfNode::SetFirstSprite()
+    {
+    if ( iParent->iSpriteChild )
+        {
+        // pass over the previous first child and make it my sibling
+        iSibling = iParent->iSpriteChild;
+        }
+    // jealously make me the first child
+    iParent->iSpriteChild = (CAlfNodeSprite*)this;
+    }
+
+// ---------------------------------------------------------------------------
+// FindParentGroup
+// ---------------------------------------------------------------------------
+//
+TUint32 CAlfNode::FindParentGroup()
+    {
+    // go back in parents, until a group node is found. return its id.
+    if ( iType == MWsWindowTreeNode::EWinTreeNodeSprite )
+        {
+        if ( iParent->iType == MWsWindowTreeNode::EWinTreeNodeRoot )
+            {
+            return 0;
+            }
+        else
+            {
+            return iParent->iId; // TODO: THIS IS ROOT, MIGHT NOT BE ALWAYS
+            }
+        }
+    
+    
+    if ( iType == MWsWindowTreeNode::EWinTreeNodeRoot )
+        {
+        return 0;
+        }
+    ASSERT( iParent );
+    CAlfNode* parent = iParent;
+    while( parent->iType != MWsWindowTreeNode::EWinTreeNodeGroup )
+        {
+        parent = parent->iParent;
+        }
+    return parent->iId;
+    }
+
+// ---------------------------------------------------------------------------
+// GetAllChildrenInGroup
+// ---------------------------------------------------------------------------
+//
+void CAlfNode::GetAllChildrenInGroup( RPointerArray<CAlfNode>& aNodes, TUint32 aParentId )
+	{
+	if ( iParent->iType != MWsWindowTreeNode::EWinTreeNodeRoot)
+		{
+		CAlfNode* parentGroupNode = iModel->FindNode( aParentId );
+		for (CAlfNode::TIter iter( parentGroupNode ); iter.Current() != NULL;  iter.Next()) 
+			{ 
+			aNodes.Append(iter.Current()); 
+			}
+		}
+	else
+		{
+		CAlfNode* child = iParent->iChild;
+		do
+			{
+			aNodes.Append( child );
+			child = child->iSibling; 
+			}
+		while( child );
+		}
+	}
+
+// ---------------------------------------------------------------------------
+// OrdinalPosition
+// ---------------------------------------------------------------------------
+//
+TInt CAlfNode::OrdinalPosition()
+    {
+    //_LIT( KText, "OrdinalPosition");
+    __ALFLOGSTRING("CAlfNode::OrdinalPosition");
+    // __ALFLOGSTRING1("CAlfNode::OrdinalPosition - Looking for me %d", iId );
+    RPointerArray<CAlfNode> nodes;
+    TBool hasOrdinalPosition = ETrue;
+    
+    switch(iParent->iType)
+        {
+        case MWsWindowTreeNode::EWinTreeNodeClient:
+            {
+            CAlfNode* parentNode = iModel->FindNode( iParent->iId );
+            __ASSERT_DEBUG(parentNode, USER_INVARIANT());
+            if (parentNode->HasChildren())
+                {
+                // parent node is not added to the list
+                // the anims, cursor and sprites directly in this parent are added to the list
+                // siblings are added to the list, but their anims, cursors and sprites are not added
+                TraverseNodeTree( parentNode, nodes, EFalse /* list all for this node */, EFalse /* dont add me */);
+                }      
+            break;
+            }
+        case MWsWindowTreeNode::EWinTreeNodeGroup:
+            {
+            TUint32 parentId = FindParentGroup();
+            CAlfNode* parentGroupNode = iModel->FindNode( parentId );
+            //__ALFLOGSTRING1("CAlfNode::OrdinalPosition - My parent %d", parentId );        
+            CAlfNode* current;
+            if ( parentGroupNode )
+                {
+                current = parentGroupNode->iChild;
+                TraverseNodeTree( current, nodes, ETrue /* list siblings only */, ETrue /* add me */ );
+                }      
+
+            break;
+            }
+
+
+        case MWsWindowTreeNode::EWinTreeNodeRoot:
+            {
+            // Window group ordinal position calculation (their parent is EWinTreeNodeRoot)
+
+            // Root node can have window groups, sprites and perhaps anims as children.
+            // However, sprites & anims do not have ordinal position concept, but window groups do.
+            // These sprites & anims are placed to floating sprite control group in alfbridge side 
+            // and so they are excluded from ordinal position calculation.
+            CAlfNode* child = iParent->iChild;
+            if ( this == iParent->iTextCursor )
+                {
+                hasOrdinalPosition = EFalse;
+                }
+                
+            if ( hasOrdinalPosition && iParent->iSpriteChild )
+                {
+                CAlfNode* animnode = iParent->iSpriteChild ;
+                while ( animnode )
+                    {
+                    if ( this == animnode )
+                        {
+                        hasOrdinalPosition = EFalse;
+                        break;
+                        }
+                    animnode = animnode->iSibling;
+                    }
+                }
+
+            if( hasOrdinalPosition && iParent->iAnimChild )
+                {
+                CAlfNode* animnode = iParent->iAnimChild ;
+                while ( animnode )
+                    {
+                    if ( this == animnode )
+                        {
+                        hasOrdinalPosition = EFalse;
+                        break;
+                        }                    
+                    animnode = animnode->iSibling;
+                    }
+                }
+
+            if ( child )
+                {
+                do
+                    {
+                    nodes.Append( child );
+                    child = child->iSibling;
+                    }
+                while( child );
+                }
+            break;
+            }
+        }
+        
+    TInt ordinalPosition = -1;
+    if ( hasOrdinalPosition )
+        {        
+        TInt i = nodes.Count();
+        //   __ALFLOGSTRING1("Node count: %d", i );
+        // return my position in the node array
+        while( --i >=0 && nodes[i] != this ) 
+            {
+            }
+        if ( i < 0)
+            {
+            __ALFLOGSTRING1("Node %d not found!", iId);
+            __ASSERT_DEBUG( 0, USER_INVARIANT() );
+            //USER_INVARIANT();
+            }
+        else
+            {
+            __ALFLOGSTRING2("Found %d at ordinal position %d!", nodes[i]->iId, i );
+            }
+        ordinalPosition = i;
+        }
+    
+    nodes.Close();    
+    return ordinalPosition;
+    }
+
+// ---------------------------------------------------------------------------
+// CAlfNode::TraverseNodeTree
+// Traverse through node tree and fill node array 
+// ---------------------------------------------------------------------------
+//
+
+// ---------------------------------------------------------------------------
+// CAlfNode::TraverseNodeTree
+// Traverse through node tree and fill node array 
+// ---------------------------------------------------------------------------
+//
+
+void CAlfNode::TraverseNodeTree( CAlfNode* node,  RPointerArray<CAlfNode>& nodes, TBool aTraverseOnlySiblings, TBool aAddMe)
+    {
+    // Exit if we've already finished walking the tree.
+    if ( node == NULL) 
+        { 
+        __ALFLOGSTRING(" returning NULL");                                  
+        return;
+        }
+    if (!aTraverseOnlySiblings)
+        {
+        if ( node->iSpriteChild ) 
+            {
+        CAlfNode* spritenode = node->iSpriteChild ;
+            while ( spritenode )
+                {
+                nodes.Append( spritenode );                
+                spritenode = spritenode->iSibling;
+                }
+            }
+    
+        if( node->iTextCursor )
+            {
+            nodes.Append(node->iTextCursor );            
+            }
+    
+        if( node->iAnimChild )
+            {
+            CAlfNode* animnode = node->iAnimChild ;
+            while ( animnode )
+                {
+                nodes.Append( animnode );                
+                animnode = animnode->iSibling;
+                }
+            }
+        
+        if ( node->iChild)
+            {                
+            TraverseNodeTree(node->iChild , nodes, EFalse, ETrue);            
+            }
+        } 
+
+    if (aAddMe)
+        {
+        nodes.Append( node );
+        }
+
+    if ( node->iSibling )
+        {                
+        TraverseNodeTree(node->iSibling, nodes, ETrue, ETrue);               
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// OrdinalPosition
+// ---------------------------------------------------------------------------
+//
+#ifdef ALF_DEBUG_PRINT_NODE_INFO
+TInt CAlfNode::PrintOrdinalPositions()
+    {
+    TInt i = 0;
+    __ALFLOGSTRING("CAlfNode::PrintOrdinalPositions - ");
+    
+    RPointerArray<CAlfNode> nodes;
+    if ( iParent->iType != MWsWindowTreeNode::EWinTreeNodeRoot)
+        {
+        TUint32 parentId = FindParentGroup();
+        CAlfNode* parentGroupNode = iModel->FindNode( parentId );
+        for (CAlfNode::TIter iter( parentGroupNode ); iter.Current() != NULL;  iter.Next()) 
+            { 
+            nodes.Append(iter.Current()); 
+            }
+        }
+    else
+        {
+        CAlfNode* child = iParent->iChild;
+        do
+            {
+            nodes.Append( child );
+            }
+        while( ( child = child->iSibling) != NULL );
+        }
+    
+    i = nodes.Count();
+    // return my position in the node arr
+    TInt groupLevel = 0;
+    while( --i >=0  ) 
+    	{
+    	CAlfNodeVisual* node = (CAlfNodeVisual*)nodes[i];
+    	_LIT(KText, "PrintOrdinalPositions");
+    	// PrintInfo( i, node, TPtrC(KText), 0);
+    	}
+    nodes.Close();    
+    return i;
+    }
+
+void CAlfNode::PrintInfo( CAlfNode* aNode, TInt aHighLightNode, TInt aDepth)
+    {
+    HBufC16* buffer = HBufC16::NewL(256);
+    TPtr iDebugText = buffer->Des();
+    iDebugText.Format( _L(""));
+    MWsWindowTreeNode::TType type = aNode->Type();
+
+    for(TInt i = 0; i < aDepth; i++)
+        {
+        iDebugText.AppendFormat(_L(" "));
+        }
+		
+    // Print the parent id in front of every children. For debugging the debugging code...
+    //CAlfNode* parent = aNode->iParent;
+    //if (parent)
+    //	{
+	//	iDebugText.AppendFormat(_L("[0x%x] "), parent->iId);
+    //	}
+    if ( aHighLightNode == aNode->iId )
+        {
+        iDebugText.AppendFormat( _L("\n-- MODIFIED NODE -- \n"));
+        }
+
+    switch ( type )
+        {
+        case MWsWindowTreeNode::EWinTreeNodeRoot:
+            {
+            iDebugText.AppendFormat( _L("Root 0x%x"), aNode->iId);
+            break;
+            }
+        case MWsWindowTreeNode::EWinTreeNodeClient:
+            {
+            CAlfNodeVisual* nodeVisual = (CAlfNodeVisual*)aNode;
+            iDebugText.AppendFormat(_L("Client 0x%x: iTl: (%3d,%3d), size (%3dx%3d)"), nodeVisual->iId, nodeVisual->iOrigin.iX, nodeVisual->iOrigin.iY, nodeVisual->iSize.iWidth, nodeVisual->iSize.iHeight );
+                         
+            break;
+            }
+        case MWsWindowTreeNode::EWinTreeNodeGroup:
+            {
+            CAlfNodeGroup* nodeGroup = (CAlfNodeGroup*)aNode;
+            iDebugText.AppendFormat(_L("Group (%d) 0x%x: SecureId: 0x%x"), nodeGroup->iGroupId, nodeGroup->iId, nodeGroup->SecureId());
+            break;
+            }               
+        case MWsWindowTreeNode::EWinTreeNodeAnim:
+            {
+            CAlfNodeVisual* nodeVisual = (CAlfNodeVisual*)aNode;
+            iDebugText.AppendFormat(_L("Anim 0x%x: iTl: (%3d,%3d), size (%3dx%3d)"), nodeVisual->iId, nodeVisual->iOrigin.iX, nodeVisual->iOrigin.iY,nodeVisual->iSize.iWidth, nodeVisual->iSize.iHeight );
+            break;
+            }               
+        case MWsWindowTreeNode::EWinTreeNodeSprite:
+            {
+            CAlfNodeVisual* nodeVisual = (CAlfNodeVisual*)aNode;
+            iDebugText.AppendFormat(_L("Sprite 0x%x: iTl: (%3d,%3d), size (%3dx%3d)"), nodeVisual->iId, nodeVisual->iOrigin.iX, nodeVisual->iOrigin.iY,nodeVisual->iSize.iWidth, nodeVisual->iSize.iHeight );
+            break;
+            }               
+        case MWsWindowTreeNode::EWinTreeNodeStandardTextCursor:
+            {
+            // TODO, add more cursor info
+            CAlfNodeVisual* nodeVisual = (CAlfNodeVisual*)aNode;
+            iDebugText.AppendFormat(_L("Cursor 0x%x: iTl: (%3d,%3d), size (%3dx%3d)"), nodeVisual->iId, nodeVisual->iOrigin.iX, nodeVisual->iOrigin.iY,nodeVisual->iSize.iWidth, nodeVisual->iSize.iHeight );
+            break;
+            }
+        }
+    switch( type )
+    	{
+    	case MWsWindowTreeNode::EWinTreeNodeStandardTextCursor:
+    	case MWsWindowTreeNode::EWinTreeNodeSprite:
+    	case MWsWindowTreeNode::EWinTreeNodeAnim:
+    	case MWsWindowTreeNode::EWinTreeNodeClient:
+    		{
+    		CAlfNodeVisual* nodeVisual = (CAlfNodeVisual*)aNode;
+    		iDebugText.AppendFormat(_L("\t\t\t"));
+			if (nodeVisual->NonFading())
+				{
+				iDebugText.AppendFormat(_L("(NON FADING)"));
+				}
+
+			if (nodeVisual->Visible())
+				{
+				iDebugText.AppendFormat(_L("(VISIBLE)"));
+				}
+			
+			if (nodeVisual->Faded())
+				{
+				iDebugText.AppendFormat(_L("(FADED)"));
+				}
+			
+			if (nodeVisual->Activated())
+				 {
+				 iDebugText.AppendFormat(_L("(ACTIVATED)"));
+				 }
+    		}
+    	}
+    RDebug::Print(_L("%S"), &iDebugText);
+    delete buffer;
+    }
+
+void CAlfNode::PrintNodeTree(
+        CAlfNodeRoot* aNode,
+        TInt aHighlightNode)
+    {
+    if (!aNode->iLogging) // Change this value during run-time. This produces A LOT of output
+        {
+        return;
+        }
+    TInt depth(0);
+    CAlfNode::PrintSubTree((CAlfNode*)aNode,aHighlightNode, depth);
+    }
+
+void CAlfNode::PrintSubTree( CAlfNode* aNode, TInt aHighlightNode, TInt& aDepth )
+    {
+    aDepth++;
+    CAlfNode::PrintInfo(aNode, aHighlightNode, aDepth);
+   
+    CAlfNode* node = (CAlfNode*)aNode->iSpriteChild;
+       while( node )
+           {
+           CAlfNode::PrintInfo( node, aHighlightNode, aDepth + 1);
+           node = node->iSibling;
+           }
+       node = (CAlfNode*)aNode->iAnimChild;
+       while( node )
+           {
+           CAlfNode::PrintInfo(node, aHighlightNode, aDepth + 1);
+           node = node->iSibling;
+           }
+       if ( aNode->iTextCursor )
+           {
+           CAlfNode::PrintInfo( aNode->iTextCursor, aHighlightNode, aDepth + 1);
+           }
+       node = (CAlfNode*)aNode->iChild;
+       while ( node )        
+           {
+           node->PrintSubTree( node, aHighlightNode, aDepth );
+           node = node->iSibling;
+           }
+       aDepth--;
+    }
+
+ #endif
+// ---------------------------------------------------------------------------
+// TIter::TIter
+// ---------------------------------------------------------------------------
+//
+CAlfNode::TIter::TIter(CAlfNode* aTopNode) 
+        : iTopNode(aTopNode) 
+        , iCurrentNode(aTopNode),
+        iState( ESearchingSprites )
+        { 
+        // Find the first node 
+        while(iCurrentNode->iChild!=NULL) 
+                { 
+                iCurrentNode=iCurrentNode->iChild; 
+                } 
+        
+        iCurrentSibling=iCurrentNode->iSibling;        // De-reference iCurrent so it can be destroyed by caller 
+        iCurrentParent=iCurrentNode->iParent; 
+        } 
+
+// ---------------------------------------------------------------------------
+// TIter::Current
+// ---------------------------------------------------------------------------
+//
+CAlfNode* CAlfNode::TIter::Current() 
+        { 
+        return iCurrentNode; 
+        } 
+
+// ---------------------------------------------------------------------------
+// TIter::Next
+// ---------------------------------------------------------------------------
+//
+CAlfNode* CAlfNode::TIter::Next() 
+        { 
+        // Exit if we've already finished walking the tree. Do not return the group node
+        if (iCurrentNode == iTopNode || iCurrentNode == NULL) 
+                { 
+                __ALFLOGSTRING("Iter returning NULL");
+                iCurrentNode = NULL;
+                iState = ESearchingSprites;
+                return NULL; 
+                }
+        
+//Diagram shows visit order with parent (/) and sibling relationships (>) 
+//  
+//              -  14 - 
+//            /           \ 
+//          6       >       13 
+//         / \           /  |   \ 
+//        3 > 5        10 > 11 > 12 
+//       / \   \     / | \ 
+//      1 > 2   4  7 > 8 > 9 
+//  
+// 
+        // Todo.
+        // Return sprites in order
+        
+      
+        if ( iState == ESearchingSprites )
+            {
+            iMasterNode = iCurrentNode;
+                    
+            if ( iCurrentNode->iSpriteChild )
+                {
+                // TODO: As long as we are putting sprites into their own group, we cannot count their ordinals
+                //iCurrentNode = (CAlfNode*)iCurrentNode->iSpriteChild;
+                //iState = ESearchMoreSprites;
+                //return iCurrentNode;
+                iState = ESearchingTextCursor;
+                }
+            else
+                {
+                iState = ESearchingTextCursor;
+                }
+            }
+        
+        if ( iState == ESearchMoreSprites )
+            {
+            if ( iCurrentNode->iSibling )
+                {
+                iCurrentNode = iCurrentNode->iSibling;
+                return iCurrentNode;
+                
+                }
+            else
+                {
+                iCurrentNode = iMasterNode;
+                iState = ESearchingTextCursor;
+                }
+            }
+        
+        if ( iState == ESearchingTextCursor )
+            {
+            if ( iMasterNode->iTextCursor )
+                {
+                iCurrentNode = iMasterNode->iTextCursor;
+                iState = ESearchingMoreTextCursor;
+                return iCurrentNode;
+                }
+            else
+                {
+                iState = ESearchingAnims;
+                }
+            }
+        
+        if ( iState == ESearchingMoreTextCursor )
+            {
+            iCurrentNode = iMasterNode;
+            iState = ESearchingAnims;        
+            return iCurrentNode;
+        
+            }
+        
+        if ( iState == ESearchingAnims )
+            {
+            if ( iCurrentNode->iAnimChild )
+                {
+                iCurrentNode = (CAlfNode*)iCurrentNode->iAnimChild;
+                iState = ESearchMoreAnims;
+                return iCurrentNode;
+                }
+            else
+                {
+                iState = ESearchingChildWindows;
+                iChildrenProcessed = ETrue;
+                iCurrentSibling = iMasterNode->iSibling;
+                }
+            }
+        
+        if ( iState == ESearchMoreAnims )
+            {
+            if ( iCurrentNode->iSibling ) // anim sibling
+                {
+                iCurrentNode = iCurrentNode->iSibling;
+                return iCurrentNode;
+                
+                }
+            else
+                {
+                iCurrentNode = iMasterNode;
+
+                iState = ESearchingChildWindows;
+                // if this node is having children windows, then we need to go to them
+                if ( iCurrentNode->iChild )
+                    {
+                    iCurrentSibling = iCurrentNode->iChild;
+                    // Look the deepest child
+                    iCurrentNode=iCurrentSibling; 
+                    while(iCurrentNode->iChild!=NULL) 
+                        { 
+                        iCurrentNode=iCurrentNode->iChild; 
+                        } 
+                    
+                    iState = ESearchingSprites;
+                    return iCurrentNode;
+                    }
+                else
+                    {
+                    // if no children windows, then this node is done and it should be returned
+                    return iCurrentNode;
+                    }
+                }
+            }
+            
+            if ( iState == ESearchingChildWindows )
+                {
+                if (iCurrentSibling!=NULL) 
+                    { 
+                    iCurrentNode=iCurrentSibling; 
+                    while(iCurrentNode->iChild!=NULL) 
+                        { 
+                        iCurrentNode=iCurrentNode->iChild; 
+                        } 
+                    } 
+                else 
+                    { 
+                    iCurrentNode = iCurrentParent;
+                    iChildrenProcessed = EFalse;
+                    } 
+    
+                iCurrentSibling=iCurrentNode->iSibling;        // De-reference iCurrent so it can be destroyed by caller 
+                iChildrenProcessed = EFalse;
+                iState = ESearchingSprites;
+                iCurrentParent=iCurrentNode->iParent; 
+                if ( iCurrentNode == iTopNode )
+                    {
+                    iCurrentNode = NULL;
+                    }
+                return iCurrentNode; 
+                }
+        return NULL;
+        } 
+
+// ---------------------------------------------------------------------------
+// FindPreviousChild
+// ---------------------------------------------------------------------------
+//
+CAlfNode* CAlfNode::FindPreviousChild()
+    {
+    CAlfNode* previousSibling = NULL;
+    switch ( iType )
+        {
+        default:
+            {
+            previousSibling = iParent->iChild;
+            break;
+            }
+        case MWsWindowTreeNode::EWinTreeNodeAnim:
+            {
+            previousSibling = iParent->iAnimChild;
+            break;
+            }
+        case MWsWindowTreeNode::EWinTreeNodeSprite:
+            {
+            previousSibling = iParent->iSpriteChild;
+            break;
+            }
+        case MWsWindowTreeNode::EWinTreeNodeStandardTextCursor:
+            {
+            previousSibling = iParent->iTextCursor;
+            break;
+            }
+        }
+     
+    if ( previousSibling == this ) 
+        {
+        return NULL; // return NULL, if I was the first child
+        }
+    // starting from the first child, loop until this one is found.
+    
+    while( previousSibling->iSibling != this)
+        {
+        previousSibling = previousSibling->iSibling;
+        }
+    
+    return previousSibling; // return the previous child. return NULL, if this was the first child
+    }
+
+// ---------------------------------------------------------------------------
+// FadeCountChanged
+// Fade count changes are sent also to Anim, Sprite and text cursor nodes.
+// ---------------------------------------------------------------------------
+//
+void CAlfNode::FadeCountChanged( TInt aFadeCount )
+    {
+	RArray<CAlfNode*> children;
+	ListOffspring(children, EFalse); // EFalse = dont list chilren, only sprites, anims and textcursor
+	TBool fade = aFadeCount ? ETrue : EFalse;
+    
+    for(TInt i=0;i<children.Count(); i++)
+    	{
+		children[i]->SetFaded(fade);        
+    	}
+    children.Close();
+    iFadeCount = aFadeCount;
+    }
+
+// ---------------------------------------------------------------------------
+// SetFaded
+// ---------------------------------------------------------------------------
+//
+void CAlfNode::SetFaded( TBool aFaded )
+    {
+    iFadeState = aFaded && ( !iNonFading );
+    if (Type()== MWsWindowTreeNode::EWinTreeNodeRoot)
+        {
+        // NO need to deliver fades for root
+        return;
+        }
+    if (iFadeState != iPostedFadeState)
+        {
+        iModel->Server().Bridge()->AddData( EAlfDSSetFadeEffect, iId , iFadeState);
+        iPostedFadeState = iFadeState;
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// FadeAllChildren
+// ---------------------------------------------------------------------------
+//
+void CAlfNode::FadeAllChildren( TBool aFaded )
+    {
+    SetFaded(aFaded);
+    
+    CAlfNode* node = (CAlfNode*)iSpriteChild;
+    while( node )
+        {
+        node->SetFaded( iFadeState );        
+        node = node->iSibling;
+        }
+    node = (CAlfNode*)iAnimChild;
+    while( node )
+        {
+        node->SetFaded( iFadeState );       
+        node = node->iSibling;
+        }
+    if ( iTextCursor )
+        {
+        iTextCursor->SetFaded( iFadeState );
+        }
+    node = (CAlfNode*)iChild;
+    while ( node )        
+        {
+        node->FadeAllChildren( iFadeState );
+        node = node->iSibling;
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// ListOffspring
+// ---------------------------------------------------------------------------
+//
+void CAlfNode::ListOffspring( RArray<CAlfNode*>& aList, TBool aListChildren)
+    {
+    aList.Append(this);
+    
+    CAlfNode* node = (CAlfNode*)iSpriteChild;
+    while( node )
+        {
+		aList.Append(node);        
+        node = node->iSibling;
+        }
+    node = (CAlfNode*)iAnimChild;
+    while( node )
+        {
+		aList.Append(node);       
+        node = node->iSibling;
+        }
+    if ( iTextCursor )
+        {
+		aList.Append(iTextCursor);
+        }
+    if (aListChildren)
+    	{
+		node = (CAlfNode*)iChild;
+		while ( node )        
+			{
+			node->ListOffspring( aList );
+			node = node->iSibling;
+			}
+    	}
+    }
+// ---------------------------------------------------------------------------
+// FlagChanged
+// ---------------------------------------------------------------------------
+//
+void CAlfNode::FlagChanged( MWsWindowTreeObserver::TFlags aFlag, TBool aNewValue )
+    {
+    switch( aFlag )
+        {
+        case MWsWindowTreeObserver::EVisible:
+            {
+            // TODO: Do something!!!!
+            iVisible = aNewValue;
+            break;
+            }
+        case MWsWindowTreeObserver::ENonFading:
+            {
+            iNonFading = aNewValue;
+            FadeAllChildren(iFadeState);
+            break;
+            }
+        case MWsWindowTreeObserver::EAlphaChannelTransparencyEnabled:
+            {
+            iAlphaChannelTransparencyEnabled = aNewValue;
+            break;
+            }
+        case MWsWindowTreeObserver::ECursorClipRectSet:
+            {
+            // TODO: take into account with cursor 
+            // ECursorClipRectSet
+            break;
+            }
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CreateWindowAttributes
+// ---------------------------------------------------------------------------
+//
+TAny* CAlfNode::CreateWindowAttributes(TInt& aIndex, TInt aSize )
+    {
+    TAny* attributes = NULL;
+    TRAP_IGNORE(attributes = (TAny*)iModel->Server().Bridge()->AppendVarDataL( aSize, aIndex ))
+    Mem::FillZ( (TUint8*)attributes, aSize ); // Initialize the returned memory area to 0
+    return attributes;
+    }
+
+// ---------------------------------------------------------------------------
+// SiblingOrderChanged
+// ---------------------------------------------------------------------------
+//
+ void CAlfNode::SiblingOrderChanged( TInt aNewPos )
+    {
+    // __ALFLOGSTRING1("CAlfNode::SiblingOrderChanged - Id %d, Old ordinal position: %d"), iId, OrdinalPosition());
+    ASSERT( iType != MWsWindowTreeNode::EWinTreeNodeRoot); 
+    ASSERT( iType != MWsWindowTreeNode::EWinTreeNodeSprite);
+    ASSERT( iType != MWsWindowTreeNode::EWinTreeNodeAnim);
+    ASSERT( iType != MWsWindowTreeNode::EWinTreeNodeStandardTextCursor);
+    ASSERT( iType == MWsWindowTreeNode::EWinTreeNodeGroup || iType == MWsWindowTreeNode::EWinTreeNodeClient );
+    ASSERT(iParent != NULL); 
+    ASSERT(iParent->iChild != NULL); 
+    CAlfNode* previous = FindPreviousChild();
+    ASSERT( previous || this == iParent->iChild );
+        
+    
+    // Need to find the previous node to this node (oldPrevNode) 
+    // and the node previous to aNewPos (newPrevNode) 
+    // Then link oldPrevNode->iSibling to this->iSibling (unlink this node from the chain) 
+    // And  link this->iSibling to newPrevNode->iSibling (link the right hand side of this node back in) 
+    // And  link newPrevNode->iSibling to this                          (link the left hand side of this node back in) 
+
+    // Will point to the prev node for the current/old position 
+    CAlfNode* oldPrevNode = NULL; 
+    // Will point to the prev node for the new position 
+    CAlfNode* newPrevNode = NULL; 
+
+    // parent 
+    //   | 
+    //   |   0   1   2   3   4 
+    //   +-->A ->B ->C ->D ->E ->null 
+    //      ^^^ 
+    // position 0 is a special case... 
+    // if the new position is 0 then newPrevNode is the parent 
+    // if this is the leftmost sibling then oldPrevNode is the parent 
+
+    TInt iterNodePosition=0; 
+    CAlfNode* iterPrevNode = iParent; 
+    CAlfNode* iterNode = iParent->iChild;         
+
+    while (oldPrevNode == NULL || newPrevNode == NULL) 
+        { 
+        // Have we found the current/old position? 
+            if (iterNode == this) 
+                { 
+                oldPrevNode = iterPrevNode; 
+
+                if (newPrevNode == NULL && iterNodePosition != aNewPos) 
+                    { 
+                    // Found the old position first 
+                    // and not at the new position yet 
+                    // so "this" will be moving to the right 
+                    // which will cause the following nodes to move left by one 
+                    // so we need to compensate by adding one to the target position 
+                    // 
+                    //     0   1   2   3   4 
+                    // p ->A ->B ->C ->D ->E ->n  if we are moving B to position 3 then need to find D->E link (iterPrevNode->iterNode) 
+                    // p ->A ->C ->D ->B ->E ->n  but because C and D will be moving left, 
+                    //                            D->E is actually position at 4. 
+                    ++aNewPos; 
+                    }                         
+                } 
+
+            // Have we found the new position? 
+            if (iterNodePosition == aNewPos) 
+                { 
+                newPrevNode = iterPrevNode; 
+                } 
+
+            // Move onto the next node - if there is one 
+            if (iterNode != NULL) 
+                { 
+                // move to next node 
+                iterPrevNode = iterNode; 
+                iterNode = iterNode->iSibling;                 
+                ++iterNodePosition; 
+                } 
+            else 
+                { 
+                // parent 
+                //   | 
+                //   |   0   1   2   3   4 
+                //   +-->A ->B ->C ->D ->E ->null 
+                //                           ^^^ 
+                // if iterNode gets to NULL, then we must have found both matches 
+                // - i.e. either the new or current/old position is the rightmost node   
+                ASSERT(oldPrevNode!=NULL && newPrevNode!=NULL); 
+                } 
+
+            ASSERT(iterPrevNode!=NULL);                 
+        } // end while loop 
+
+    if (newPrevNode == oldPrevNode) 
+        { 
+        // we are being asked to move to our current position 
+        // nothing to do 
+
+        return; 
+        } 
+
+    // In the following example, oldPrevNode is A, this is B and newPrevNode is D - as discussed above 
+    // 
+    // Unlink this node from the chain (A->B becomes A->C, nothing points to B) 
+    //      0    1    2    3    4 
+    // p--->A-¬  B-+->C--->D--->E--->n 
+    //         \--/ 
+    if (oldPrevNode == iParent) 
+        { 
+        iParent->iChild = iSibling; 
+        } 
+    else 
+        { 
+        oldPrevNode->iSibling = iSibling; 
+        } 
+
+    // Link the right hand side of this node back in (B->C becomes B->E, B half at position 3) 
+    //      0         1    2 3  4 
+    // p--->A-------->C--->D-+->E--->n 
+    //                B-----/ 
+    if (newPrevNode == iParent) 
+        { 
+        iSibling = iParent->iChild; 
+        } 
+    else 
+        { 
+        iSibling = newPrevNode->iSibling; 
+        } 
+
+    // Link the left hand side of this node back in (D->E becomes D->B, B fully linked into position 3) 
+    //      0    1    2    3    4 
+    // p--->A--->C--->D¬     +->E--->n 
+    //                  \-B-/ 
+    if (newPrevNode == iParent) 
+        { 
+        iParent->iChild = this; 
+        } 
+    else 
+        { 
+        newPrevNode->iSibling = this; 
+        } 
+    
+    UpdateOrdinalPosition();
+    
+    if (HasChildren())
+        {
+        UpdateChildrenOrdinalPositions(this);
+        }
+    
+    /*
+    TInt ordinal = OrdinalPosition();
+    __ALFLOGSTRING1("New ordinal position: %d"), OrdinalPosition());
+#ifdef _DEBUG    
+    PrintOrdinalPositions();
+#endif    
+    TInt offset;
+    TAlfWindowAttributes* windowAttributes = (TAlfWindowAttributes*)CreateWindowAttributes(offset, sizeof(TAlfWindowAttributes));
+    windowAttributes->iOrdinalPosition = ordinal; 
+    windowAttributes->iWindowNodeType = iType;
+    windowAttributes->iScreenNumber = iScreenNumber;
+    
+    iModel->Server().Bridge()->AddData( EAlfDSReorder, 
+            iGroupId, 
+            iId, 
+            (TAny*)offset );
+            */
+            
+            
+    }
+
+// ---------------------------------------------------------------------------
+// destructor
+// ---------------------------------------------------------------------------
+// 
+CAlfNode::~CAlfNode()
+    {
+    __ALFLOGSTRING1("CAlfNode::~CAlfNode %d", iId);
+    }
+
+// ---------------------------------------------------------------------------
+// HasChildren
+// ---------------------------------------------------------------------------
+// 
+TBool CAlfNode::HasChildren()
+    {
+    return iSpriteChild || iAnimChild || iTextCursor || iChild;
+    }
+
+// ---------------------------------------------------------------------------
+// RemoveDependencies
+// ---------------------------------------------------------------------------
+// 
+void CAlfNode::RemoveDependencies( CAlfNode* aFirstChildOfMyType )
+    {
+    // if I have siblings, then make my previous sibling's next sibling, that used to be my next sibling
+    /*if ( iParent )
+        {
+        __ALFLOGSTRING1( "%d %d %d %d"), iParent->iChild , iParent->iSpriteChild , iParent->iAnimChild, iParent->iTextCursor );
+        }*/
+
+    if ( iModel && iParent && aFirstChildOfMyType )
+        {
+        CAlfNode* previousSibling = FindPreviousChild();
+        if ( previousSibling )
+            {
+            previousSibling->iSibling = iSibling;
+            }
+        else
+            {
+            // If we do not have previous sibling
+            switch ( iType )
+                {
+                default:
+                    {
+                    iParent->iChild = iSibling; // Parent's child needs to change ONLY IF I was the first one.
+                    break;
+                    }
+                case MWsWindowTreeNode::EWinTreeNodeAnim:
+                    {
+                    iParent->iAnimChild = (CAlfNodeAnim*)iSibling;
+                    break;
+                    }
+                case MWsWindowTreeNode::EWinTreeNodeSprite:
+                    {
+                    iParent->iSpriteChild = (CAlfNodeSprite*)iSibling;
+                    break;
+                    }
+                }
+            
+            }
+        }
+    else
+        {
+        __ALFLOGSTRING1("My parent says, that I'm not his child :..( or no parent %d ", iParent );
+        }
+    
+    // Orphon all the children
+    CAlfNode* child = iChild; 
+    while( child )
+        {
+        child = child->OrphonMe();
+        }
+    iChild = NULL;
+    if ( iModel )
+        {    
+        iModel->RemoveNode( iId );
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// Constructor
+// ---------------------------------------------------------------------------
+//
+CAlfNodeVisual::CAlfNodeVisual() 
+    {
+    iWindow =  NULL;
+    };
+
+// ---------------------------------------------------------------------------
+// Constructor
+// ---------------------------------------------------------------------------
+//
+void CAlfNodeVisual::ConstructL( CAlfHierarchyModel* aModel, RMemReadStream* aStream )
+	{
+	CAlfNode::ConstructL( aModel, aStream );
+    aStream->ReadL( (TUint8*)&iOrigin, sizeof(TPoint));
+    aStream->ReadL( (TUint8*)&iSize, sizeof(TSize));
+	}
+
+// ---------------------------------------------------------------------------
+// ReadEndMarkerL
+// ---------------------------------------------------------------------------
+//
+void CAlfNodeVisual::ReadEndMarkerL( RMemReadStream& aStream )
+    {
+    TUint8 marker = aStream.ReadInt8L();
+    ASSERT( marker == EAlfCommandEndMarker ) ; // endmarker
+    }
+ 
+// ---------------------------------------------------------------------------
+// UpdateOrdinalPosition
+// ---------------------------------------------------------------------------
+//
+void CAlfNode::UpdateOrdinalPosition()
+    {
+    TInt ordinal = OrdinalPosition();
+    if ( ordinal >= 0 )
+        {
+        if ( iWindow )
+            {
+            iWindow->Move( ordinal );
+            }
+        else
+            {
+            //!!!! There is no window???
+            // position must be updated, because it not necessary the first drawn.
+            TInt offset;
+            TAlfWindowAttributes* windowAttributes = (TAlfWindowAttributes*)CreateWindowAttributes(offset, sizeof(TAlfWindowAttributes));
+            windowAttributes->iOrdinalPosition = ordinal; 
+            windowAttributes->iWindowNodeType = iType;
+            windowAttributes->iScreenNumber = iScreenNumber;
+            // for updating window group ordinals
+            iModel->Server().Bridge()->AddData( EAlfDSReorder, 
+                    iGroupId, 
+                    iId, 
+                    (TAny*)offset );
+            }
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// UpdateChildrenOrdinalPositions
+// ---------------------------------------------------------------------------
+//
+void CAlfNode::UpdateChildrenOrdinalPositions(CAlfNode* aNode)
+    {
+    CAlfNode* node = (CAlfNode*)aNode->iSpriteChild;
+    while( node )
+        {
+        node->UpdateOrdinalPosition();
+        node = node->iSibling;
+        }
+    node = (CAlfNode*)aNode->iAnimChild;
+    while( node )
+        {
+        node->UpdateOrdinalPosition();
+        node = node->iSibling;
+        }
+    if ( aNode->iTextCursor )
+        {
+        (aNode->iTextCursor)->UpdateOrdinalPosition();
+        }
+    node = (CAlfNode*)aNode->iChild;
+    while ( node )        
+        {
+        node->UpdateChildrenOrdinalPositions(node);
+        node->UpdateOrdinalPosition();
+        node = node->iSibling;
+        }
+
+    }
+
+// ---------------------------------------------------------------------------
+// CommitCommandsL
+// ---------------------------------------------------------------------------
+//
+void CAlfNodeVisual::CommitCommands( TInt aCurrentPos, TInt aFrameSize, TBool aPartial, TBool aLastPart, TInt aChunkInUse  )
+    {
+    // __ALFLOGSTRING1("CAlfNodeVisual::CommitCommandsL, Id/Group: %d/%d Type: %d, Pos: %d, Size: %d, last part %d"), iId, iGroupId, iType, aCurrentPos, aFrameSize, aLastPart );
+    if ( !iWindow )
+        {
+        __ALFLOGSTRING("CAlfHierarchyModel::CommitCommandsL Discarding window commands");
+        return;
+        }
+
+    if ( !aFrameSize )
+        {
+        __ALFLOGSTRING3("CAlfHierarchyModel::CommitCommandsL empty frame Pos: %d, Size: %d, last part %d ", aCurrentPos, aFrameSize, aLastPart );
+        return;
+        }
+    
+    TBool emptyBuffer = EFalse;
+    
+    TInt nodeFlags = 0;
+
+    // By default nodes are always opaque, unless they are sprites (or anims?) or
+    // transparency has been enabled in the window.    
+    if (iType != MWsWindowTreeNode::EWinTreeNodeSprite && 
+        iType != MWsWindowTreeNode::EWinTreeNodeAnim &&
+       iType != MWsWindowTreeNode::EWinTreeNodeStandardTextCursor &&
+        !iAlphaChannelTransparencyEnabled)
+        {
+        nodeFlags |= EAlfWinNodeFlagOpaque;         
+        }
+        
+    if ( iType == MWsWindowTreeNode::EWinTreeNodeStandardTextCursor )
+        {
+        emptyBuffer = ETrue;
+        }
+       
+    iWindow->PostPartialBuffer( iModel->ChunkBase(aChunkInUse) + aCurrentPos, aFrameSize, aPartial, aLastPart , emptyBuffer, nodeFlags );
+    }
+
+// ---------------------------------------------------------------------------
+// DrawWindowFrameL
+// ---------------------------------------------------------------------------
+void CAlfNodeVisual::DrawWindowFrameL( RMemReadStream& aStream )
+    {
+    TInt32 chunkInUse = aStream.ReadInt32L();
+    TInt nextFramePos = aStream.ReadInt32L();
+       
+    // jump to the next frame
+    if ( nextFramePos == 12345678 )
+        {
+        __ALFLOGSTRING("CAlfHierarchyModel::PostBufferL, Address of the frame has not been initialized!");
+        }
+    // read frame flags. For offscreen content, we'll add the complete packets 
+     // as partial, if they have not been implicitly flushed 
+     
+     TUint8 command = aStream.ReadInt8L();
+     __ASSERT_DEBUG( command == EAlfFrameFlags, USER_INVARIANT() );
+     TInt32 frameFlags = aStream.ReadInt32L();
+
+    TUint8 padding = aStream.ReadInt8L();
+    ReadEndMarkerL( aStream );
+    while( padding--)
+        {
+        aStream.ReadInt8L();
+        }
+        
+    TInt currentPos = aStream.Source()->TellL( MStreamBuf::ERead ).Offset();
+    aStream.Source()->SeekL( MStreamBuf::ERead, TStreamPos(nextFramePos));
+    TSgcCanvasCommands packetState = (TSgcCanvasCommands)aStream.ReadInt8L();
+    TInt frameSize = nextFramePos - currentPos;
+#ifdef _DEBUG
+    ASSERT( currentPos % 8 == 0 );
+#endif
+    
+    //__ALFLOGSTRING1("CAlfHierarchyModel::PostBufferL endMarker: %d partial: %d"), endMarker, iReadingPartialBuffer );
+    switch( packetState )
+        {
+        case EAlfPacketReady:
+            {
+            if ( frameFlags & EAlfTransparentContent )
+                {
+                if ( frameFlags & EAlfTransparentContentFlush  )
+                    {
+                    CommitCommands( currentPos, frameSize, !iReadingPartialBuffer /*partial*/, ETrue /*lastpart*/, chunkInUse );
+                    }
+                else
+                    {
+                    CommitCommands( currentPos, frameSize, ETrue /*partial*/, EFalse/*not lastpart*/, chunkInUse );
+                    }
+                }
+            else
+                {
+                CommitCommands( currentPos, frameSize, iReadingPartialBuffer, ETrue, chunkInUse );
+                }
+            iReadingPartialBuffer = EFalse;
+                            
+            break;
+            }
+        case EAlfPacketNotReady:
+            {
+            __ASSERT_DEBUG( nextFramePos % 8 == 0, USER_INVARIANT() );
+            __ASSERT_DEBUG( frameSize % 8 == 0, USER_INVARIANT() );
+            iReadingPartialBuffer = ETrue;
+            CommitCommands( currentPos, frameSize, iReadingPartialBuffer, EFalse, chunkInUse );
+            break;
+            }
+        default:
+            {
+            __ALFLOGSTRING1("CAlfHierarchyModel::PostBufferL endMarker: %d ", packetState);
+            break;
+            }
+        }
+    }
+
+
+// ---------------------------------------------------------------------------
+// FlagChanged
+// ---------------------------------------------------------------------------
+//
+void CAlfNodeVisual::FlagChanged( MWsWindowTreeObserver::TFlags aFlag, TBool aNewValue )
+    {
+    switch( aFlag )
+        {
+        case MWsWindowTreeObserver::EVisible:
+            {
+            iVisible = aNewValue;
+            if ( iWindow )
+            	{
+            	if ( iVisible && iNodeActivated )
+            		{
+            		iWindow->SetActive( ETrue );
+            		}
+            	else
+            		{
+                    iWindow->SetActive( EFalse );
+            		}
+            	}
+            break;
+            }
+        case MWsWindowTreeObserver::ENonFading:
+            {
+            iNonFading = aNewValue;
+            SetFaded(iFadeState);
+            break;
+            }
+        case MWsWindowTreeObserver::EAlphaChannelTransparencyEnabled:
+            {
+            iAlphaChannelTransparencyEnabled = aNewValue;
+            break;
+            }
+        }
+    if ( aFlag == MWsWindowTreeObserver::ENonFading && HasChildren() )
+        {
+        UpdateChildrenFlags( aFlag, iFadeState );
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// UpdateChildrenFlags
+// ---------------------------------------------------------------------------
+//
+void CAlfNodeVisual::UpdateChildrenFlags( MWsWindowTreeObserver::TFlags aFlag, TBool aNewValue )
+    {
+    CAlfNode* node = (CAlfNode*)iSpriteChild;
+    while( node )
+        {
+        node->FlagChanged( aFlag, aNewValue );
+        node = node->iSibling;
+        }
+    node = (CAlfNode*)iAnimChild;
+    while( node )
+        {
+        node->FlagChanged( aFlag, aNewValue );
+        node = node->iSibling;
+        }
+    if ( iTextCursor )
+        {
+        iTextCursor->FlagChanged( aFlag, aNewValue );
+        }
+    node = (CAlfNode*)iChild;
+    while ( node )
+        
+        {
+        node->FlagChanged( aFlag, aNewValue ); // causes recursion on children
+        node = node->iSibling;
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// SetExtent
+// ---------------------------------------------------------------------------
+//
+void CAlfNodeVisual::SetExtent( TRect& aRect )
+    {
+	// aRect is in screen coordinates whereas iOrigin and iSize are relative.
+    if ( iSize != aRect.Size() )
+    	{
+    	iSize = aRect.Size();
+    	if ( iWindow) 
+    		{
+    		iWindow->SetSize(iSize,0);
+    		}
+    	}
+  	// Recursively, TODO, check this with flash example
+   	TPoint parentPosition; 
+   	CAlfNodeVisual* parent = (CAlfNodeVisual*)iParent;
+   	while(parent)
+   	    {
+        if(parent->Type() != MWsWindowTreeNode::EWinTreeNodeGroup)
+            { // parent 
+            parentPosition += parent->iOrigin;
+            parent = (CAlfNodeVisual*)parent->iParent;
+            }
+        else
+            {
+            break;
+            }
+                
+    	}
+            
+    TPoint newOrigin = aRect.iTl - parentPosition;
+    if ( iOrigin != newOrigin )
+    	{            
+    	iOrigin = newOrigin;
+    	if (iWindow)
+    		{
+    		iWindow->SetPos(iOrigin, 0 );
+    		/*if (HasChildren())
+    		    {
+    		    UpdateChildrenExtents(posDelta);
+    		    }*/
+    		// __ALFLOGSTRING1("CAlfNodeVisual, SetPos %d,%d, iType %d"), iOrigin.iX, iOrigin.iY, iType );
+    		}
+    	}
+    // __ALFLOGSTRING1("CAlfNodeVisual, SetExtent iSize: %d,%d ; iPosition %d,%d "), iSize.iWidth, iSize.iHeight, iOrigin.iX, iOrigin.iY ); 
+    }
+
+void CAlfNodeVisual::UpdateParentPosition(TPoint aPosDelta)
+    {
+    // iParentPosition = aRect.iTl;
+    // iParentSize = aRect.Size();
+    
+    // Todo, size change?
+    if (iWindow)
+        {
+        iOrigin += aPosDelta;
+        iWindow->SetPos( iOrigin, 0 );
+        UpdateChildrenExtents(aPosDelta);
+        // __ALFLOGSTRING1("CAlfNodeVisual, SetPos %d,%d, iType %d"), iOrigin.iX, iOrigin.iY, iType );
+        }
+
+    }
+
+void CAlfNodeVisual::UpdateChildrenExtents(TPoint aPosDelta)
+    {
+        CAlfNode* node = (CAlfNode*)iSpriteChild;
+        while( node )
+            {
+            ((CAlfNodeVisual*)node)->UpdateParentPosition(aPosDelta);
+            node = node->iSibling;
+            }
+        node = (CAlfNodeVisual*)iAnimChild;
+        while( node )
+            {
+            ((CAlfNodeVisual*)node)->UpdateParentPosition(aPosDelta);
+            node = node->iSibling;
+            }
+        if ( iTextCursor )
+            {
+            ((CAlfNodeVisual*)iTextCursor)->UpdateParentPosition(aPosDelta);
+            }
+        node = (CAlfNodeVisual*)iChild;
+        while ( node )        
+            {
+            ((CAlfNodeVisual*)node)->UpdateChildrenExtents(aPosDelta);
+            ((CAlfNodeVisual*)node)->UpdateParentPosition(aPosDelta);
+                        
+            node = node->iSibling;
+            }
+        }
+
+// ---------------------------------------------------------------------------
+// ActivateNodeL
+// ---------------------------------------------------------------------------
+//
+void CAlfNodeVisual::ActivateNode()
+     { 
+     if ( !iNodeActivated)
+         {
+         iNodeActivated = ETrue;
+        
+         if ( iWindow )
+            {
+        	if ( iVisible )
+        		{
+        		iWindow->SetActive( ETrue );
+        		}
+        	}
+         }
+     else
+         {
+         __ALFLOGSTRING("CAlfNodeVisual::ActivateNodeL - Node ALREADY active! ");
+         }
+     }
+
+
+// ---------------------------------------------------------------------------
+// CreateWindowL
+// ---------------------------------------------------------------------------
+void CAlfNodeVisual::CreateWindowL(TInt aWindowGroupHandle, TInt aWindowHandle, TInt aParentWindowHandle)
+    {
+    TWindowIdentifier windowIdentifier( iGroupId, iId );
+    TWindowIdentifier clientSideIdentifier( aWindowGroupHandle, aWindowHandle );
+    TWindowIdentifier parentIdentifier( 0, aParentWindowHandle ); // Group id not used, set to zero.
+    
+    TAlfWServInfo info;     
+    info.iSize = iSize;
+    info.iPosition = iOrigin;    
+    info.iRefId = windowIdentifier; // Node ids   
+    info.iClientSideId = clientSideIdentifier; // Client handles
+    info.iNodeType = iType;
+    info.iScreenNumber = iScreenNumber;    
+    info.iParentRefId = parentIdentifier;
+#ifdef ALF_DEBUG_TRACK_DRAWING    
+    info.iTrackWindow = iTrackNode;
+#endif
+    iWindow = iModel->Server().WindowMgr()->CreateNewWindowL( iId, info );
+    iWindow->CommitGc();
+    }
+
+// ---------------------------------------------------------------------------
+// destructor
+// ---------------------------------------------------------------------------
+//
+CAlfNodeVisual::~CAlfNodeVisual()
+    {
+    if ( iWindow && iModel )
+        {
+        iModel->Server().WindowMgr()->DestroyWindow( *iWindow );
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// Constructor
+// ---------------------------------------------------------------------------
+//
+CAlfNodeWindow::CAlfNodeWindow()
+    {
+    iType = MWsWindowTreeNode::EWinTreeNodeClient;
+    };
+
+CAlfNodeWindow::~CAlfNodeWindow()
+    {
+    RemoveDependencies( iParent ? iParent->iChild : NULL );
+    }
+// ---------------------------------------------------------------------------
+// ConstructL
+// ---------------------------------------------------------------------------
+//
+void CAlfNodeWindow::ConstructL( CAlfHierarchyModel* aModel, RMemReadStream* aStream  )
+	{
+	CAlfNodeVisual::ConstructL( aModel, aStream );
+	aStream->ReadL( (TUint8*)&iNodeWindowConstructionStruct, sizeof( TNodeWindowConstructionStruct ) );
+    iOrdinalPriority = iNodeWindowConstructionStruct.iOrdinalPriority;
+    ResolveParent( iNodeWindowConstructionStruct.iParentId, iId );
+    CreateWindowL( iNodeWindowConstructionStruct.iWindowGroupHandle, iNodeWindowConstructionStruct.iWindowHandle, iNodeWindowConstructionStruct.iParentId );
+    UpdateOrdinalPosition();
+	}
+
+// ---------------------------------------------------------------------------
+// MoveToWindowGroup
+// !!!! THIS METHOD HAS NOT BEEN TESTED AT ALL!!!!!! EXPECT TROUBLE!!!!
+// ---------------------------------------------------------------------------
+//
+void CAlfNodeWindow::MoveToWindowGroup( TUint32 aNewGroupId )
+	{
+	__ALFLOGSTRING("CAlfNodeWindow::MoveToWindowGroup, THIS METHOD IS UNTESTED. EXPECT TROUBLE!");
+	CAlfNodeGroup* newGroup = (CAlfNodeGroup*)iModel->FindNode( aNewGroupId );
+	if ( newGroup )
+		{
+		// collect my children in my old group
+		RPointerArray<CAlfNode> myChildNodes;
+		GetAllChildrenInGroup( myChildNodes, iId );
+			    
+		// release old relationships
+		CAlfNode* previous = FindPreviousChild();
+		if ( !previous )
+			{
+			iParent->iChild = iSibling; // I was the first and possibly only child
+			}
+		else
+			{
+			previous->iSibling = iSibling; // there was the a previous child. update the link to my next sibling (which might be NULL)
+			}
+		TUint32 oldGroupId = iParent->iId;
+		iParent = newGroup;
+		SetFirstChild();
+		
+		// yippii, new parent, 		
+		// add me as the first child of the new group
+		// TODO: Move the nodes to the new group?
+		TInt i = myChildNodes.Count();
+		while( --i >=0 ) // update groupid and send new location to appui 
+			{
+			iModel->Server().Bridge()->AddData( EAlfDSMoveWindowToNewGroup, 
+					myChildNodes[i]->iId, 
+					oldGroupId, 
+					(TAny*)aNewGroupId );
+			myChildNodes[i]->iGroupId = aNewGroupId;
+			}
+	  
+		myChildNodes.Close();
+		}
+	else
+		{
+		__ALFLOGSTRING("CAlfNodeWindow::MoveToWindowGroupL, new group does not exists");
+		USER_INVARIANT();
+		}
+	}
+
+// ---------------------------------------------------------------------------
+// NewL
+// ---------------------------------------------------------------------------
+//
+CAlfNodeWindow* CAlfNodeWindow::NewL( CAlfHierarchyModel* aModel, RMemReadStream* aStream, TInt aScreenNumber  )
+    {
+    CAlfNodeWindow* self = new(ELeave)CAlfNodeWindow();
+    CleanupStack::PushL( self );
+    self->iScreenNumber = aScreenNumber;
+    self->ConstructL( aModel, aStream ); 
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// ---------------------------------------------------------------------------
+// Construct
+// ---------------------------------------------------------------------------
+//
+CAlfNodeRoot::CAlfNodeRoot( )
+    {
+    iType = MWsWindowTreeNode::EWinTreeNodeRoot;
+    }
+
+// ---------------------------------------------------------------------------
+// ConstructL
+// ---------------------------------------------------------------------------
+//
+void CAlfNodeRoot::ConstructL( CAlfHierarchyModel* aModel, RMemReadStream* aStream  )
+	{
+	CAlfNodeVisual::ConstructL( aModel, aStream );
+	
+	// TODO: 
+	ResolveParent( 0, iId );
+	CreateWindowL(0,0,0); // Currently renderstage does not deliver ws/wg handles
+	}
+
+// ---------------------------------------------------------------------------
+// NewL
+// ---------------------------------------------------------------------------
+//
+CAlfNodeRoot* CAlfNodeRoot::NewL( CAlfHierarchyModel* aModel, RMemReadStream* aStream, TInt aScreenNumber  )
+    {
+    CAlfNodeRoot* self = new(ELeave)CAlfNodeRoot();
+    CleanupStack::PushL( self );
+    self->iScreenNumber = aScreenNumber;
+    self->ConstructL( aModel, aStream ); 
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// ---------------------------------------------------------------------------
+// destructor
+// ---------------------------------------------------------------------------
+//
+CAlfNodeRoot::~CAlfNodeRoot( )
+    {
+    // TODO: destroy all children nodes?
+    RemoveDependencies( NULL );
+    }
+
+// ---------------------------------------------------------------------------
+// Constructor
+// ---------------------------------------------------------------------------
+//
+CAlfNodeGroup::CAlfNodeGroup()
+    {
+    iType = MWsWindowTreeNode::EWinTreeNodeGroup;
+    }
+
+// ---------------------------------------------------------------------------
+// ConstructL
+// ---------------------------------------------------------------------------
+//
+void CAlfNodeGroup::ConstructL( CAlfHierarchyModel* aModel, RMemReadStream* aStream  )
+	{
+	CAlfNode::ConstructL( aModel, aStream );
+    TInt32 clientHandle = aStream->ReadUint32L();
+    iSecureId = aStream->ReadUint32L();
+    TInt32 parentId = aStream->ReadUint32L();
+    
+    ResolveParent( parentId, iId );
+    
+    TInt offset;
+    TAlfWindowAttributes* windowAttributes = (TAlfWindowAttributes*)CreateWindowAttributes(offset, sizeof(TAlfWindowAttributes));
+    windowAttributes->iWindowNodeType = iType; 
+    windowAttributes->iClientHandle = clientHandle;
+    windowAttributes->iScreenNumber = iScreenNumber;
+    windowAttributes->iSecureId = iSecureId;
+    windowAttributes->iParentNodeId = parentId;
+	
+    iModel->Server().Bridge()->AddData( EAlfDSNewWindow, 
+            iGroupId, 
+            iId, 
+            (TAny*)offset );
+	}
+
+// ---------------------------------------------------------------------------
+// NewL
+// ---------------------------------------------------------------------------
+//
+CAlfNodeGroup* CAlfNodeGroup::NewL( CAlfHierarchyModel* aModel, RMemReadStream* aStream , TInt aScreenNumber )
+    {
+    CAlfNodeGroup* self = new(ELeave)CAlfNodeGroup();
+    CleanupStack::PushL( self );
+    self->iScreenNumber = aScreenNumber;
+    self->ConstructL( aModel, aStream ); 
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// ---------------------------------------------------------------------------
+// WindowGroupChainedL
+// ---------------------------------------------------------------------------
+//
+void CAlfNodeGroup::WindowGroupChained( TUint32 aChainedGroup )
+	{
+	iChainedTo = (CAlfNodeGroup*)iModel->FindNode( aChainedGroup );
+	if ( iChainedTo )
+		{
+		iChainedTo->iChainedFrom = this;
+		}
+	else
+		{
+		USER_INVARIANT();
+		}
+	
+    if (iModel)
+        {
+        iModel->Server().Bridge()->AddData( EAlfDSGroupChained, 
+                iId, 
+                aChainedGroup, 
+                (TAny*)iScreenNumber
+                );                
+        }
+	}
+
+// ---------------------------------------------------------------------------
+// GroupChainBrokenAfter
+// ---------------------------------------------------------------------------
+//
+void CAlfNodeGroup::GroupChainBrokenAfter(  )
+	{
+	if ( iChainedTo )
+		{
+		iChainedTo->iChainedFrom = NULL;
+		iChainedTo = NULL;
+		}
+	if (iModel)
+		{
+		iModel->Server().Bridge()->AddData( EAlfDSGroupChainBroken, 
+				iId, 
+				0, 
+				(TAny*)iScreenNumber );                
+		}
+
+	}
+
+
+// ---------------------------------------------------------------------------
+// destructor
+// ---------------------------------------------------------------------------
+//
+CAlfNodeGroup::~CAlfNodeGroup()
+    {
+    if ( iChainedTo )
+    	{
+    	GroupChainBrokenAfter();
+    	}
+    if ( iChainedFrom )
+    	{
+    	iChainedFrom->iChainedTo = NULL;
+    	}
+    
+    if (iModel)
+        {
+        TInt offset;
+        TAlfWindowAttributes* windowAttributes = (TAlfWindowAttributes*)CreateWindowAttributes(offset, sizeof(TAlfWindowAttributes));
+        windowAttributes->iWindowNodeType = iType; 
+        windowAttributes->iScreenNumber = iScreenNumber; 
+
+        iModel->Server().Bridge()->AddData( EAlfDSDestroyWindow, 
+                iGroupId, 
+                iId, 
+                (TAny*)offset );                
+        }
+    RemoveDependencies( iParent->iChild );
+    };
+
+// ---------------------------------------------------------------------------
+// constructor
+// ---------------------------------------------------------------------------
+//
+CAlfNodeAnim::CAlfNodeAnim( )
+    {
+    iType = MWsWindowTreeNode::EWinTreeNodeAnim;
+     }
+
+CAlfNodeAnim::~CAlfNodeAnim( )
+    {
+    if ( iParent )
+        {
+        RemoveDependencies( iParent->iAnimChild );
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// ConstructL
+// ---------------------------------------------------------------------------
+//
+void CAlfNodeAnim::ConstructL( CAlfHierarchyModel* aModel, RMemReadStream* aStream  )
+	{
+	CAlfNodeVisual::ConstructL( aModel, aStream );
+	TInt32 parentId = aStream->ReadUint32L();
+
+	// TODO: 
+	ResolveParent( parentId, iId );
+	CreateWindowL(0,0,iParent->iId); // Currently renderstage does not deliver ws/wg handles
+	UpdateOrdinalPosition();
+	}
+
+// ---------------------------------------------------------------------------
+// NewL
+// ---------------------------------------------------------------------------
+//
+CAlfNodeAnim* CAlfNodeAnim::NewL( CAlfHierarchyModel* aModel, RMemReadStream* aStream, TInt aScreenNumber  )
+    {
+    CAlfNodeAnim* self = new(ELeave)CAlfNodeAnim();
+    CleanupStack::PushL( self );
+    self->iScreenNumber = aScreenNumber;
+    self->ConstructL( aModel, aStream ); 
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+
+// ---------------------------------------------------------------------------
+// constructor
+// ---------------------------------------------------------------------------
+//
+CAlfNodeSprite::CAlfNodeSprite( )
+    {
+    iType = MWsWindowTreeNode::EWinTreeNodeSprite;
+    }
+
+CAlfNodeSprite::~CAlfNodeSprite( )
+    {
+    if ( iParent )
+        {
+        RemoveDependencies( iParent->iSpriteChild );
+        }
+    }
+// ---------------------------------------------------------------------------
+// ConstructL
+// ---------------------------------------------------------------------------
+//
+void CAlfNodeSprite::ConstructL( CAlfHierarchyModel* aModel, RMemReadStream* aStream  )
+	{
+	CAlfNodeVisual::ConstructL( aModel, aStream );
+	TInt32 parentId = aStream->ReadUint32L();
+
+	// TODO: 
+	ResolveParent( parentId, iId );
+	CreateWindowL(0,0,iParent->iId); // Currently renderstage does not deliver ws/wg handles
+	// Sprite may not be first in its group
+	UpdateOrdinalPosition();
+	}
+
+// ---------------------------------------------------------------------------
+// NewL
+// ---------------------------------------------------------------------------
+//
+CAlfNodeSprite* CAlfNodeSprite::NewL( CAlfHierarchyModel* aModel, RMemReadStream* aStream, TInt aScreenNumber  )
+    {
+    CAlfNodeSprite* self = new(ELeave)CAlfNodeSprite();
+    CleanupStack::PushL( self );
+    self->iScreenNumber = aScreenNumber;
+    self->ConstructL( aModel, aStream ); 
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// ---------------------------------------------------------------------------
+// constructor
+// ---------------------------------------------------------------------------
+//
+CAlfNodeTextCursor::CAlfNodeTextCursor( )
+    {
+    iType = MWsWindowTreeNode::EWinTreeNodeStandardTextCursor;
+    }
+
+// ---------------------------------------------------------------------------
+// ConstructL
+// ---------------------------------------------------------------------------
+//
+void CAlfNodeTextCursor::ConstructL( CAlfHierarchyModel* aModel, RMemReadStream* aStream  )
+    {
+    CAlfNode::ConstructL( aModel, aStream );
+    iCursorType = aStream->ReadInt32L();
+    aStream->ReadL( (TUint8*)&iRect, sizeof(TRect));
+    aStream->ReadL( (TUint8*)&iClipRect, sizeof(TRect));
+    iSize = iRect.Size();
+    iOrigin = iRect.iTl;
+    
+    iFlags = aStream->ReadInt32L();
+    iColor = aStream->ReadInt32L();
+    iFlashInterval = aStream->ReadInt32L(); 
+    TInt32 parentId = aStream->ReadUint32L();
+    
+    // TODO: 
+    ResolveParent( parentId, iId );
+    
+    CreateWindowL(0,0,iParent->iId); // Currently renderstage does not deliver ws/wg handles
+    TInt offset;
+    // pass rest of the cursor data
+    TAlfCursorDataBufferAttributes* attributes = (TAlfCursorDataBufferAttributes*)CreateWindowAttributes(offset, sizeof(TAlfCursorDataBufferAttributes));
+    attributes->iColor = iColor;
+    attributes->iFlags = iFlags;
+    attributes->iFlashInterval = iFlashInterval;
+    attributes->iScreenNumber = iScreenNumber;
+    
+    aModel->Server().Bridge()->AddData( EAlfDSSetCursorData, 
+            iGroupId, 
+            iId, 
+            (TAny*)offset );
+    
+    UpdateOrdinalPosition();
+    }
+
+// ---------------------------------------------------------------------------
+// NewL
+// ---------------------------------------------------------------------------
+//
+CAlfNodeTextCursor* CAlfNodeTextCursor::NewL( CAlfHierarchyModel* aModel, RMemReadStream* aStream, TInt aScreenNumber  )
+    {
+    CAlfNodeTextCursor* self = new(ELeave)CAlfNodeTextCursor();
+    CleanupStack::PushL( self );
+    self->iScreenNumber = aScreenNumber;
+    self->ConstructL( aModel, aStream ); 
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+void CAlfNodeTextCursor::AttributeChangedL( RMemReadStream* aStream )
+    {
+    // TODO: PASS FORWARD!!!
+    TInt attribute = aStream->ReadInt32L();
+    switch ( attribute )
+        {
+        case MWsWindowTreeObserver::ECursorType:
+            {
+            iCursorType = aStream->ReadInt32L();
+            break;
+            }
+        case MWsWindowTreeObserver::ECursorClipRect:
+            {
+            aStream->ReadL( (TUint8*)&iClipRect, sizeof(TRect));
+            break;
+            }
+
+        case MWsWindowTreeObserver::ECursorFlags:
+            {
+            iFlags = aStream->ReadInt32L();
+            break;
+            }
+
+        case MWsWindowTreeObserver::ECursorColor:
+            {
+            iColor = aStream->ReadInt32L();
+            break;
+            }
+        }
+    TInt offset;
+    TAlfCursorDataBufferAttributes* attributes = (TAlfCursorDataBufferAttributes*)CreateWindowAttributes(offset, sizeof(TAlfCursorDataBufferAttributes));
+       attributes->iColor = iColor;
+       attributes->iFlags = iFlags;
+       attributes->iFlashInterval = iFlashInterval;
+       attributes->iScreenNumber = iScreenNumber;
+       __ALFLOGSTRING("Forwarding cursor data");
+       iModel->Server().Bridge()->AddData( EAlfDSSetCursorData, 
+               iGroupId, 
+               iId, 
+               (TAny*)offset );
+    }
+CAlfNodeTextCursor::~CAlfNodeTextCursor( )
+    {
+    // text cursor is the only text cursor in its parent. No need to check siblings.
+    if(iParent)
+        {
+        iParent->iTextCursor = NULL;
+        }
+    // RemoveNode is called instead of RemoveDependeciesL, because this node has no depencies.
+    if(iModel)
+        {
+        iModel->RemoveNode( iId );
+        }
+    }
+
+// end of file
+