diff -r 000000000000 -r 15bf7259bb7c uiacceltk/hitchcock/ServerCore/Src/alfnodes.cpp --- /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 +#include + +#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& 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 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& 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 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 children; + ListOffspring(children, EFalse); // EFalse = dont list chilren, only sprites, anims and textcursor + TBool fade = aFadeCount ? ETrue : EFalse; + + for(TInt i=0;iSetFaded(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& 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 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 +