--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/photosgallery/viewframework/uiutilities/src/glxvisualutilities.cpp Thu Dec 17 08:45:44 2009 +0200
@@ -0,0 +1,167 @@
+/*
+* Copyright (c) 2008-2009 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: ALF visual utilities
+*
+*/
+
+
+
+
+// CLASS HEADER
+#include "glxvisualutilities.h"
+
+// EXTERNAL HEADERS
+#include <uiacceltk/huicontrol.h>
+#include <uiacceltk/huivisual.h>
+
+namespace NGlxVisualUtilities
+ {
+ /**
+ * TGlxVisualTransferCleanup
+ * This class handles the awkward situation in visual ownership transfer
+ * that some of the visuals are transferred to new parent and a leave occurs.
+ * In leave case we need to undo the ownership transfer completely.
+ * This class also removes the ownership from the old control in case
+ * there was no leave.
+ * @usage:
+ * \code
+ * RArray<CHuiVisual*> allvisuals;
+ * TGlxVisualTransferCleanup cleanup( allvisuals );
+ * // set the parent to remove from to be the new one
+ * cleanup.iParentToRemoveFrom = aNewParent;
+ * CleanupClosePushL( cleanup );
+ * // start to append the visuals to the new parent
+ * // in case of leave they are removed from new parent
+ * RecurseAndTransferVisualsL( visualcleanup, aVisual, aNewParent );
+ * // set the parent to remove to be the old one
+ * cleanup.iParentToRemoveFrom = oldParent;
+ * // remove the item from cleanupstack,
+ * // this removes the visuals from their old parent
+ * CleanupStack::PopAndDestroy( &cleanup );
+ * \endcode
+ */
+ NONSHARABLE_CLASS( TGlxVisualTransferCleanup )
+ {
+ public:
+
+ /**
+ * Constructor.
+ * @param aArray, the array of Visuals
+ * @param aOldParent, the old parent of visuals
+ * @param aNewParent, the new parent for visuals
+ */
+ inline TGlxVisualTransferCleanup(
+ RArray<CHuiVisual*>& aArray )
+ : iArray( aArray )
+ {
+ }
+
+ /**
+ * Close. Put this class to Cleanupstack with
+ * CleanupClosePushL so that this gets called in case of a leave
+ */
+ inline void Close()
+ {
+ // need to remove all visuals from the given parent
+ // loop through all the CHuiVisuals
+ for( TInt i = 0; i < iArray.Count(); ++i )
+ {
+ // remove from the given parent
+ iParentToRemoveFrom->Remove( iArray[ i ] );
+ }
+ // reset the array
+ iArray.Reset();
+ }
+
+ /// Ref: the parent where to remove
+ MHuiVisualOwner* iParentToRemoveFrom;
+
+ private: // Implementation
+
+ /// Ref: the array containing all the visuals
+ RArray<CHuiVisual*>& iArray;
+
+ };
+
+ /**
+ * Recursive helper method to transfer the ownership of visuals
+ * @param aVisualCleanup an array containing all visuals in the hierarchy
+ * @param aVisual the visual to move to new control
+ * @param aNewParent the new parent for the visual
+ */
+ void RecurseAndTransferVisualsL(
+ RArray<CHuiVisual*>& aVisualCleanup,
+ CHuiVisual& aVisual, CHuiControl& aNewParent )
+ {
+ // make room to the pointer so that we always succeed in appending
+ // Note that we need to make room for one new item, thus count + 1
+ aVisualCleanup.ReserveL( aVisualCleanup.Count() + 1 );
+ // append us to the new parent, Note that for a while we are
+ // owner by two controls but thats not a problem as the other parent
+ // is removed by either TGlxVisualTransferCleanup.Close() by CleanupStack
+ // or destructor of TGlxVisualTransferCleanup and there is no other way
+ // of getting out from this method (of course panic is ;)
+ aNewParent.AppendL( &aVisual );
+ // add us in the cleanuparray so that we can be removed from the
+ // new parent in case some of the following AppendLs leave
+ // this does not fail as reserve was called so no AppendL needed
+ aVisualCleanup.Append( &aVisual );
+ // check if the visual has childs
+ TInt childCount = aVisual.Count();
+ // transfer all the childs
+ while( childCount-- > 0 )
+ {
+ // get the child
+ CHuiVisual& childVisual = aVisual.Visual( childCount );
+ // call transfer recursively on the child
+ RecurseAndTransferVisualsL(
+ aVisualCleanup, childVisual, aNewParent );
+ }
+ }
+
+ // -------------------------------------------------------------------------
+ // TransferVisualsL
+ // -------------------------------------------------------------------------
+ EXPORT_C void TransferVisualsL(
+ CHuiVisual& aVisual, CHuiControl& aNewParent )
+ {
+ // check if parent is already correct
+ if( &( aVisual.Owner() ) ==
+ static_cast< MHuiVisualOwner* >( &aNewParent ) )
+ {
+ // nothing else to be done
+ return;
+ }
+ // create an array for visual pointers on the stack
+ RArray< CHuiVisual* > visualcleanup;
+ // create the cleanup item from stack as well
+ TGlxVisualTransferCleanup removeParent( visualcleanup );
+ // set the parent to remove from to be the new one
+ removeParent.iParentToRemoveFrom = &aNewParent;
+ // need to remember the old parent
+ MHuiVisualOwner* oldParent = &( aVisual.Owner() );
+ // put it to cleanupstack so that close gets called in case of leave
+ CleanupClosePushL( removeParent );
+ // run the recursive loop, if it leaves the visuals are removed from
+ // new parent by the Close method of cleanParents
+ RecurseAndTransferVisualsL( visualcleanup, aVisual, aNewParent );
+ // set the parent to remove to be the old one
+ removeParent.iParentToRemoveFrom = oldParent;
+ // remove the item from cleanupstack,
+ // this removes the visuals from the old parent
+ CleanupStack::PopAndDestroy( &removeParent );
+ // close the array
+ visualcleanup.Close();
+ }
+ }