photosgallery/viewframework/uiutilities/src/glxvisualutilities.cpp
branchRCL_3
changeset 24 ea65f74e6de4
parent 23 b023a8d2866a
child 25 8e5f6eea9c9f
equal deleted inserted replaced
23:b023a8d2866a 24:ea65f74e6de4
     1 /*
       
     2 * Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:    ALF visual utilities
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 // CLASS HEADER
       
    22 #include "glxvisualutilities.h"
       
    23 
       
    24 // EXTERNAL HEADERS
       
    25 #include <uiacceltk/huicontrol.h>
       
    26 #include <uiacceltk/huivisual.h>
       
    27 
       
    28 namespace NGlxVisualUtilities
       
    29     {
       
    30     /**
       
    31      * TGlxVisualTransferCleanup
       
    32      * This class handles the awkward situation in visual ownership transfer
       
    33      * that some of the visuals are transferred to new parent and a leave occurs.
       
    34      * In leave case we need to undo the ownership transfer completely.
       
    35      * This class also removes the ownership from the old control in case
       
    36      * there was no leave.
       
    37      * @usage:
       
    38      * \code
       
    39      *      RArray<CHuiVisual*> allvisuals;
       
    40      *      TGlxVisualTransferCleanup cleanup( allvisuals );
       
    41      *       // set the parent to remove from to be the new one
       
    42      *      cleanup.iParentToRemoveFrom = aNewParent;
       
    43      *      CleanupClosePushL( cleanup );
       
    44      *      // start to append the visuals to the new parent
       
    45      *      // in case of leave they are removed from new parent
       
    46      *      RecurseAndTransferVisualsL( visualcleanup, aVisual, aNewParent );
       
    47      *      // set the parent to remove to be the old one
       
    48      *      cleanup.iParentToRemoveFrom = oldParent;
       
    49      *      // remove the item from cleanupstack,
       
    50      *      // this removes the visuals from their old parent 
       
    51      *      CleanupStack::PopAndDestroy( &cleanup );
       
    52      * \endcode
       
    53      */
       
    54     NONSHARABLE_CLASS( TGlxVisualTransferCleanup )
       
    55     	{
       
    56     	public:
       
    57 
       
    58             /**
       
    59     		 * Constructor.
       
    60     		 * @param aArray, the array of Visuals 
       
    61     		 * @param aOldParent, the old parent of visuals
       
    62     		 * @param aNewParent, the new parent for visuals
       
    63     		 */
       
    64     		inline TGlxVisualTransferCleanup( 
       
    65                 RArray<CHuiVisual*>& aArray )
       
    66                 : iArray( aArray )
       
    67     			{
       
    68                 }
       
    69 
       
    70             /**
       
    71              * Close. Put this class to Cleanupstack with 
       
    72              * CleanupClosePushL so that this gets called in case of a leave
       
    73              */
       
    74             inline void Close()
       
    75                 {
       
    76                 // need to remove all visuals from the given parent
       
    77                 // loop through all the CHuiVisuals
       
    78                 for( TInt i = 0; i < iArray.Count(); ++i )
       
    79                     {
       
    80                     // remove from the given parent
       
    81                     iParentToRemoveFrom->Remove( iArray[ i ] );
       
    82                     }
       
    83                 // reset the array
       
    84                 iArray.Reset();
       
    85                 }
       
    86 
       
    87             /// Ref: the parent where to remove
       
    88             MHuiVisualOwner* iParentToRemoveFrom;
       
    89 
       
    90         private: // Implementation
       
    91 
       
    92             /// Ref: the array containing all the visuals
       
    93             RArray<CHuiVisual*>& iArray; 
       
    94 
       
    95     	};
       
    96 
       
    97     /**
       
    98      * Recursive helper method to transfer the ownership of visuals
       
    99      * @param aVisualCleanup an array containing all visuals in the hierarchy
       
   100      * @param aVisual the visual to move to new control
       
   101      * @param aNewParent the new parent for the visual
       
   102      */
       
   103     void RecurseAndTransferVisualsL(
       
   104         RArray<CHuiVisual*>& aVisualCleanup,
       
   105         CHuiVisual& aVisual, CHuiControl& aNewParent )
       
   106         {
       
   107         // make room to the pointer so that we always succeed in appending
       
   108         // Note that we need to make room for one new item, thus count + 1
       
   109         aVisualCleanup.ReserveL( aVisualCleanup.Count() + 1 );
       
   110         // append us to the new parent, Note that for a while we are
       
   111         // owner by two controls but thats not a problem as the other parent 
       
   112         // is removed by either TGlxVisualTransferCleanup.Close() by CleanupStack
       
   113         // or destructor of TGlxVisualTransferCleanup and there is no other way
       
   114         // of getting out from this method (of course panic is ;)
       
   115         aNewParent.AppendL( &aVisual );
       
   116         // add us in the cleanuparray so that we can be removed from the 
       
   117         // new parent in case some of the following AppendLs leave
       
   118         // this does not fail as reserve was called so no AppendL needed
       
   119         aVisualCleanup.Append( &aVisual );
       
   120         // check if the visual has childs
       
   121         TInt childCount = aVisual.Count();
       
   122         // transfer all the childs
       
   123         while( childCount-- > 0 )
       
   124             {
       
   125             // get the child
       
   126             CHuiVisual& childVisual = aVisual.Visual( childCount );
       
   127             // call transfer recursively on the child
       
   128             RecurseAndTransferVisualsL( 
       
   129                 aVisualCleanup, childVisual, aNewParent );
       
   130             }
       
   131         }
       
   132 
       
   133     // -------------------------------------------------------------------------
       
   134 	// TransferVisualsL
       
   135 	// -------------------------------------------------------------------------
       
   136     EXPORT_C void TransferVisualsL( 
       
   137         CHuiVisual& aVisual, CHuiControl& aNewParent )
       
   138         {
       
   139         // check if parent is already correct
       
   140         if( &( aVisual.Owner() ) == 
       
   141             static_cast< MHuiVisualOwner* >( &aNewParent ) )
       
   142             {
       
   143             // nothing else to be done
       
   144             return;
       
   145             }
       
   146         // create an array for visual pointers on the stack
       
   147         RArray< CHuiVisual* > visualcleanup;
       
   148         // create the cleanup item from stack as well
       
   149         TGlxVisualTransferCleanup removeParent( visualcleanup );
       
   150         // set the parent to remove from to be the new one
       
   151         removeParent.iParentToRemoveFrom = &aNewParent;
       
   152         // need to remember the old parent
       
   153         MHuiVisualOwner* oldParent = &( aVisual.Owner() );
       
   154         // put it to cleanupstack so that close gets called in case of leave
       
   155         CleanupClosePushL( removeParent );
       
   156         // run the recursive loop, if it leaves the visuals are removed from
       
   157         // new parent by the Close method of cleanParents
       
   158         RecurseAndTransferVisualsL( visualcleanup, aVisual, aNewParent );
       
   159         // set the parent to remove to be the old one
       
   160         removeParent.iParentToRemoveFrom = oldParent;
       
   161         // remove the item from cleanupstack,
       
   162         // this removes the visuals from the old parent 
       
   163         CleanupStack::PopAndDestroy( &removeParent );
       
   164         // close the array
       
   165         visualcleanup.Close();
       
   166         }
       
   167     }