uifw/EikStd/coctlsrc/EIKMENUP.CPP
changeset 0 2f259fa3e83a
child 4 8ca85d2f0db7
child 14 3320e4e6e8bb
equal deleted inserted replaced
-1:000000000000 0:2f259fa3e83a
       
     1 /*
       
     2 * Copyright (c) 2002-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:  Implementation of EIKON Menu Pane class (options menu).
       
    15 *
       
    16 */
       
    17 
       
    18 // INCLUDE FILES
       
    19 
       
    20 #include <eikmenup.h>
       
    21 #include <eikmenub.h>
       
    22 #include <eikmobs.h>
       
    23 #include <eikon.hrh>
       
    24 #include <eikpanic.h>
       
    25 #include <coemain.h>
       
    26 #include <basched.h>
       
    27 #include <barsread.h>
       
    28 #include <eikhkeyt.h>
       
    29 #include <eikbutb.h>
       
    30 #include <eikenv.h>
       
    31 #include <eikcoctl.rsg>
       
    32 #include <gulcolor.h>
       
    33 #include <gulutil.h>
       
    34 #include <eikappui.h>
       
    35 #include <eiksbfrm.h>
       
    36 #include <eikscrlb.h>
       
    37 #include <gulicon.h>
       
    38 #include <aknborders.h>     // AKNLAF
       
    39 #include <aknenv.h>
       
    40 #include <AknUtils.h>
       
    41 #include <aknpopuplayout.h>
       
    42 #include <bidi.h>  // Bidirectional support
       
    43 #include <bidivisual.h>
       
    44 #include <aknconsts.h>
       
    45 #include <avkon.mbg>
       
    46 #include <AknsDrawUtils.h>
       
    47 #include <AknsFrameBackgroundControlContext.h>
       
    48 #include <AknBidiTextUtils.h>
       
    49 #include <AknMarqueeControl.h>
       
    50 #include <skinlayout.cdl.h>
       
    51 #include <aknlayoutscalable_avkon.cdl.h>
       
    52 #include <AknLayoutFont.h>
       
    53 
       
    54 #include <AknsUtils.h>
       
    55 #include <AknIconUtils.h>
       
    56 #include <aknappui.h>
       
    57 
       
    58 #include <AknsEffectAnim.h>
       
    59 #include <systemwarninglevels.hrh>
       
    60 #include <layoutmetadata.cdl.h>
       
    61 #include <AknStatuspaneUtils.h>
       
    62 #include <aknCharMap.h>
       
    63 #include <gfxtranseffect/gfxtranseffect.h> //For transition effects
       
    64 #include <akntranseffect.h> //For transition effects
       
    65 #include <akntransitionutils.h> // SetAllParents method
       
    66 #include <featmgr.h>
       
    67 #include <hal.h>
       
    68 #include <avkondomainpskeys.h>
       
    69 #include <e32property.h>
       
    70 
       
    71 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
    72 #include <aknlistboxtfxinternal.h> // LISTBOX EFFECTS IMPLEMENTATION
       
    73 #include <aknlistloadertfx.h>
       
    74 #include <aknlistboxtfx.h>
       
    75 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
    76 
       
    77 #include <touchfeedback.h>
       
    78 #include <AknTasHook.h>
       
    79 #include <aknphysics.h>
       
    80 #include <aknphysicsobserveriface.h>
       
    81 #include <aknPriv.hrh>
       
    82 #include "aknitemactionmenudata.h"
       
    83 #include "akntrace.h"
       
    84 
       
    85 // CONSTANTS
       
    86 const TInt KItemGranularity = 4;
       
    87 const TInt KAlternativeSubmenuWidths = 5; // five alternative widths for submenus depending on max text width
       
    88 const TInt KNoSelectedRadioButtonItem = -1;
       
    89 
       
    90 // Delay before opening sub menu when dragging, 0.3s
       
    91 const TInt KCascadeMenuOpenDelay = 300000;
       
    92 
       
    93 class CRedirectionListener;
       
    94 
       
    95 // -----------------------------------------------------------------------------
       
    96 // TaskSwapCallBack
       
    97 // -----------------------------------------------------------------------------
       
    98 //
       
    99 TInt TaskSwapCallBack( TAny* )
       
   100     {
       
   101     CEikonEnv::Static()->DisplayTaskList();
       
   102     return EFalse;
       
   103     }
       
   104 
       
   105 // =============================================================================
       
   106 // Extension class declaration & definition
       
   107 // =============================================================================
       
   108 /*
       
   109  * CEikMenuPaneExtension
       
   110  *
       
   111  * Structure containing extra local private data members.
       
   112  * Created to preserve BC.  The CEikMenuPane class contains a pointer to this structure
       
   113  * CEikmenuPane is responsible for data members of this class.
       
   114  *
       
   115  * Extension now contains menu/submenu highlight animation functionality.
       
   116  */
       
   117 NONSHARABLE_CLASS( CEikMenuPaneExtension ):
       
   118     public CActive,
       
   119     public MCoeForegroundObserver,
       
   120     public MAknsEffectAnimObserver,
       
   121     public MCoeControlObserver,
       
   122     public MAknPhysicsObserver    
       
   123     {
       
   124 public:
       
   125     enum TFlag
       
   126         {
       
   127         /**
       
   128         * If set, animation creation is attempted. If not set, animation will
       
   129         * never be created.
       
   130         */
       
   131         EFlagUseAnimation = 0
       
   132         };
       
   133         
       
   134     enum TScreen
       
   135         {
       
   136         EQhdHeight = 360,
       
   137         EQhdWidth = 640        
       
   138         };        
       
   139 
       
   140     CEikMenuPaneExtension();
       
   141     ~CEikMenuPaneExtension();
       
   142 
       
   143     void ConstructL( CEikMenuPane* aControl );
       
   144     void CreateAnimation();
       
   145     void NoAnimIfError( TInt aError );
       
   146     void UseNoAnimation();
       
   147     void FocusGained();
       
   148     void FocusLost();
       
   149 
       
   150     void HandleLayoutSwitch();
       
   151     void ChangeHighlightBackground();
       
   152     void MenuClosed();
       
   153 
       
   154     void ConstructMenuSctRowL( TDes& aSpecialChars, TInt aResourceId );
       
   155     void ConstructMenuSctRowFromDialogL( TDes& aSpecialChars, TInt aResourceId );
       
   156     
       
   157     void StartCascadeMenuTimerL();
       
   158     void StopCascadeMenuTimer();
       
   159     static TInt CascadeMenuTimerCallBack( TAny* aThis );
       
   160     TBool IsCascadeMenuTimerActive();
       
   161     
       
   162     void StartHighlightTimerL();
       
   163     void ResetPressedHighlight();
       
   164     static TInt HighlightTimerCallBack( TAny* aThis );
       
   165     TBool HighlightTimerActive() const;
       
   166     
       
   167     void ChangePosition( TPointerEvent& aPointerEvent );
       
   168     void CalculateParentEvent( const TPointerEvent& aPointerEvent, 
       
   169                                TPointerEvent& aParentEvent );
       
   170     TRect GetBackgroundRect( const TRect& aWindowRect ) const;                               
       
   171     static void AdjustPopupLayoutData( TAknWindowLineLayout& aListScrollPaneLayout );
       
   172                                
       
   173     const TAknLayoutText GetMenuItemTextLayout(const TRect& aItemRect, TBool cascade);
       
   174 
       
   175 public: // Implementation of MCoeForegroundObserver
       
   176     void HandleGainingForeground();
       
   177     void HandleLosingForeground();
       
   178 
       
   179 public: // Implementation of MAknsEffectAnimObserver
       
   180     void AnimFrameReady( TInt aError, TInt );
       
   181     void HandleControlEventL(CCoeControl* aControl,TCoeEvent aEventType);
       
   182 
       
   183 protected: // CActive overloads
       
   184     void DoCancel();
       
   185     void RunL();
       
   186 
       
   187 private: // New internal methods
       
   188     void Play();
       
   189     TBool DrawHighlightBackground( CFbsBitGc& aGc );
       
   190     void PostDeleteAnimation();
       
   191     void CreateAnimationL( const TSize& aHighlightSize );
       
   192     void DoResizeL( const TSize& aHighlightSize, TBool aAboutToStart );
       
   193 public:
       
   194     void ImmediateFeedback( TTouchLogicalFeedback aType,
       
   195                             TTouchFeedbackType aFbType );
       
   196     
       
   197 public:
       
   198     void StartCascadeMenuAppearTransition();
       
   199 
       
   200 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   201     void CalcItemSize( MAknListBoxTfxInternal* transApi ) const;
       
   202 #endif
       
   203 
       
   204     /**
       
   205      * Prepares cascade menu for item specific commands.
       
   206      */
       
   207     void PrepareCascadeForItemCommands();
       
   208 
       
   209     /**
       
   210      * Returns ETrue if this menu pane belongs to a CS menu.
       
   211      * 
       
   212      * @return ETrue if this menu pane belongs to a CS menu.
       
   213      */
       
   214     TBool ContextSensitiveMenu() const;
       
   215 
       
   216     /**
       
   217      * Returns ETrue if item is item specific command and the command is not
       
   218      * dimmed.
       
   219      * 
       
   220      * @param aItem Menu pane item.
       
   221      * @return ETrue if item is item specific command.
       
   222      */
       
   223     static TBool ItemSpecificCommand( CEikMenuPaneItem& aItem );
       
   224 
       
   225     /**
       
   226      * Enables or disables highlight
       
   227      * 
       
   228      * @param aEnabled ETrue to enable highlight, EFalse to disable.
       
   229      * @param aPointerEnabled ETrue if highlight was enabled due
       
   230      * to a pointer event.
       
   231      */
       
   232     void EnableHighlight( TBool aEnabled, TBool aPointerEnabled = EFalse );
       
   233 
       
   234     /**
       
   235      * Is highlight enabled
       
   236      * 
       
   237      * @return ETrue if highlight is enabled
       
   238      */
       
   239     TBool  HighlightEnabled();
       
   240 
       
   241     /**
       
   242      * Sets the default highlight to options menu
       
   243      * 
       
   244      */    
       
   245     void SetDefaultHighlight();
       
   246     
       
   247 public: // Data
       
   248     TBool iHasIcon;
       
   249     TBool iIsPenEnable;   
       
   250     CFbsBitmap* iCascadeBitmap;
       
   251     CFbsBitmap* iCascadeBitmapMask;
       
   252     CAknsFrameBackgroundControlContext* iBgContext;
       
   253     TInt        iSubMenuWidthIndex;       // index for submenu layout which depends on the text length
       
   254     CFbsBitmap* iCheckMarkBitmap;         // bitmap to be drawn if the item has check box set on
       
   255     CFbsBitmap* iCheckMarkBitmapMask;     // mask for the above bitmap
       
   256     CFbsBitmap* iRadioButtonBitmap;       // bitmap to be drawn if the item has radio button set on
       
   257     CFbsBitmap* iRadioButtonBitmapMask;   // mask for the above bitmap
       
   258     TBool       iHasRadioGroup;           // is ETrue if submenu contains radio button group.
       
   259     TInt        iSelectedRadioButtonItem; // index of the radio button item which is currently selected (one must be selected)
       
   260     CCoeControl* iGrabbingCBAComponent;    // component control of CBA which is currently grabbing the pointer
       
   261     CEikMenuPane* iControl;
       
   262     CAknsEffectAnim* iAnimation;
       
   263     /**
       
   264     * Stored flags are explained in enumeration TFlags.
       
   265     */
       
   266     TBitFlags32 iAnimFlags;
       
   267 
       
   268     CAknCharMap* iSct;      // Menu SCT row, created only when needed.
       
   269     TBool iSctHighlighted;  // No "normal" menu item can be highlighted if ETrue
       
   270 
       
   271     // Pen event related flag indicating whether the (sub)menu pane has
       
   272     // already consumed EButton1Down or not. If false,
       
   273     // EButton1Up will do nothing.
       
   274     TBool iItemsReadyForPenSelection;
       
   275     TBool iSpecialCharPointed;
       
   276     // transition demarcation rectangle for cascaded submenu
       
   277     // needs to be mutable since we need to get information from Draw methods
       
   278     // (that are declared const)
       
   279     mutable TRect iCascadeDRect;
       
   280     TBool iTransitionsOn;   // Transitions FtMgr flag on
       
   281     TBool iShowCascadeTransition;
       
   282     // For later deletion of cascade menu, this allows the transition system
       
   283     // to correctly handle the aborted transitions
       
   284     CEikMenuPane* iCascadeMenuObject;
       
   285     TBool iDraggedOutside;    
       
   286     TPointerEvent iLastPointerEvent;
       
   287 
       
   288 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   289     CWindowGc* iGc;
       
   290 #endif
       
   291     TInt iItemsThatFitInView;
       
   292     TRect iScrollBarRect;
       
   293     TRect iSctRect;
       
   294     TInt iTotalNumberOfItemsInView; // this value includes partial items
       
   295 
       
   296 
       
   297     CIdle* iTaskSwapIdle;
       
   298     CRedirectionListener* iRedirectionListener;
       
   299     TRect iSBRect;
       
   300     RWindow* iMenuPaneWindow; // Not own, used by SCT
       
   301     TBool iLaunchCascadeMenu; 
       
   302     TBool isUpdateScrollDirectly;
       
   303     TBool iPressedDown;      // ETrue if pointer is down, otherwise.
       
   304 
       
   305     CEikCba* iCba; // Embedded cba
       
   306     TRect iMenuPaneRect; // Menu area of options menu
       
   307     TBool iDownOnMenuArea; // Down event received inside menu area
       
   308     TBool iDownOnCbaArea; // Down event received inside embedded CBA area
       
   309     
       
   310     /**
       
   311      * Menu pane extension flags definition.
       
   312      */
       
   313     enum TCEikMenuPaneExtensionFlags
       
   314         {
       
   315         ESingleClickEnabled,
       
   316         EHideItemSpecificCommands,
       
   317         EContextSensitive,
       
   318         EHighlightEnabled
       
   319         };
       
   320 
       
   321     /**
       
   322      * Menu pane extension flags.
       
   323      */
       
   324     TBitFlags iFlags;
       
   325 
       
   326 private: // Data
       
   327     CPeriodic* iTimer; // timer to launch submenu, own
       
   328     CPeriodic* iHighlightTimer; // Timer to adjust pressed down highlight
       
   329     TInt iVerticalOffset; // Panning offset
       
   330 
       
   331 public: // MAknPhysicsObserver
       
   332     virtual void ViewPositionChanged( const TPoint& aNewPosition,
       
   333                                       TBool aDrawNow = ETrue,
       
   334                                       TUint aFlags = 0 );
       
   335     virtual void PhysicEmulationEnded();    
       
   336     virtual TPoint ViewPosition() const;
       
   337     
       
   338 public:    
       
   339     void InitPhysicsL();
       
   340     void DoOffset( TInt aOffset );
       
   341     void RestoreOffset( TInt aKeyCode );
       
   342     void SetOffset( TInt aOffset );
       
   343     inline TInt Offset() const { return iVerticalOffset; };
       
   344     
       
   345     CAknPhysics *iPhysics; 
       
   346     TPoint iViewPosition; // Current view position
       
   347  
       
   348     TInt iListTopIndex;
       
   349     TInt iListBottomIndex;
       
   350     
       
   351     TInt iViewHeight;
       
   352     TBool iFlickActive;
       
   353     TBool iPanningActive;
       
   354     TBool iKeyEventActive;
       
   355     
       
   356     // For dragging
       
   357     TPoint iStartPoint;
       
   358     TTime iStartTime;
       
   359     TPoint iPrevPoint;
       
   360     
       
   361     // For highlight
       
   362     TInt iButtonDownItem; // Item on which down event came
       
   363     TInt iNextHighlightItem; // Item waiting for highlight timer
       
   364     // When doing a full redraw drawitem should not
       
   365     // draw the background because draw has already
       
   366     // drawn it.
       
   367     TBool iFullRedraw;
       
   368     MTouchFeedback* iFeedback;
       
   369     // The top item index is stored to this member and used for controlling
       
   370     // tactile feedback when panning/flicking (feedback is only given when
       
   371     // new item comes into view, i.e. when the top item index changes)
       
   372     TInt iLastFeedbackTopItemIndex;
       
   373     };
       
   374 
       
   375 //
       
   376 // CEikMenuPane::CMenuScroller
       
   377 //
       
   378 
       
   379 class CEikMenuPane::CMenuScroller : public CBase, public MEikScrollBarObserver
       
   380     {
       
   381 private:    
       
   382     friend class CEikMenuPaneExtension;
       
   383 public:
       
   384     static CMenuScroller* NewL( CEikMenuPane& aMenu );
       
   385     ~CMenuScroller();
       
   386 
       
   387     inline TInt TopItemIndex() const;
       
   388     inline void SetTopItemIndex( TInt aIndex );
       
   389     inline CIdle* Idle() const;
       
   390 public: // from MEikScrollBarObserver
       
   391     void HandleScrollEventL( CEikScrollBar* aScrollBar, TEikScrollEvent aEventType );
       
   392 private:
       
   393     CMenuScroller( CEikMenuPane& aMenu );
       
   394     void ConstructL();
       
   395 private:
       
   396     CEikMenuPane& iMenuPane;
       
   397     TInt iTopItemIndex;
       
   398     CIdle* iIdle;
       
   399     };
       
   400 
       
   401 // -----------------------------------------------------------------------------
       
   402 // CEikMenuPane::CMenuScroller::NewL
       
   403 // -----------------------------------------------------------------------------
       
   404 //
       
   405 CEikMenuPane::CMenuScroller* CEikMenuPane::CMenuScroller::NewL( CEikMenuPane& aMenuPane )
       
   406     { // static
       
   407     CMenuScroller* self = new(ELeave)CMenuScroller( aMenuPane );
       
   408     CleanupStack::PushL(self);
       
   409     self->ConstructL();
       
   410     CleanupStack::Pop();
       
   411     return self;
       
   412     }
       
   413 
       
   414 // -----------------------------------------------------------------------------
       
   415 // CEikMenuPane::CMenuScroller::~CMenuScroller
       
   416 // -----------------------------------------------------------------------------
       
   417 //
       
   418 CEikMenuPane::CMenuScroller::~CMenuScroller()
       
   419     {
       
   420     delete iIdle;
       
   421     }
       
   422 
       
   423 // -----------------------------------------------------------------------------
       
   424 // CEikMenuPane::CMenuScroller::CMenuScroller
       
   425 // -----------------------------------------------------------------------------
       
   426 //
       
   427 CEikMenuPane::CMenuScroller::CMenuScroller( CEikMenuPane& aMenuPane )
       
   428     : iMenuPane( aMenuPane ), iTopItemIndex( 0 )
       
   429     {}
       
   430 
       
   431 // -----------------------------------------------------------------------------
       
   432 // CEikMenuPane::CMenuScroller::ConstructL
       
   433 // -----------------------------------------------------------------------------
       
   434 //
       
   435 void CEikMenuPane::CMenuScroller::ConstructL()
       
   436     {
       
   437     iIdle = CIdle::NewL( CActive::EPriorityIdle );
       
   438     }
       
   439 
       
   440 // -----------------------------------------------------------------------------
       
   441 // CEikMenuPane::CMenuScroller::HandleScrollEventL
       
   442 // -----------------------------------------------------------------------------
       
   443 //
       
   444 void CEikMenuPane::CMenuScroller::HandleScrollEventL( CEikScrollBar* aScrollBar,
       
   445                                                      TEikScrollEvent aEventType )
       
   446     {
       
   447     iMenuPane.HandleScrollEventL( aScrollBar, aEventType );
       
   448     }
       
   449 
       
   450 inline TInt CEikMenuPane::CMenuScroller::TopItemIndex() const
       
   451     { return iTopItemIndex; }
       
   452 
       
   453 inline void CEikMenuPane::CMenuScroller::SetTopItemIndex(TInt aIndex)
       
   454     { 
       
   455     iTopItemIndex=aIndex;
       
   456 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   457     if ( iMenuPane.iExtension )
       
   458         {
       
   459         iTopItemIndex = aIndex;
       
   460         }
       
   461 #endif
       
   462     }
       
   463 
       
   464 inline CIdle* CEikMenuPane::CMenuScroller::Idle() const
       
   465     { return iIdle; }
       
   466 
       
   467 
       
   468 void CEikMenuPaneExtension::InitPhysicsL()
       
   469     {
       
   470     _AKNTRACE_FUNC_ENTER;
       
   471            
       
   472     iVerticalOffset = 0;
       
   473     iListTopIndex = 0;
       
   474     iLastFeedbackTopItemIndex = 0;
       
   475     iPressedDown = EFalse;
       
   476     iFlickActive = EFalse;
       
   477     
       
   478     TRect rect;
       
   479     if ( !iControl->iOwner )
       
   480         {
       
   481         rect = iMenuPaneRect;    
       
   482         }
       
   483     else
       
   484         {
       
   485         rect = iControl->Rect();    
       
   486         }    
       
   487     
       
   488     TInt itemHeight = iControl->iItemHeight;
       
   489     TInt itemsInRect = rect.Height() / itemHeight;
       
   490     TInt totalItemHeight = iControl->TotalItemHeight();
       
   491 
       
   492     iViewHeight = itemsInRect * itemHeight;
       
   493     
       
   494     TSize totalSize( rect.Width(), totalItemHeight );
       
   495     TSize viewSize( rect.Width(), iViewHeight );
       
   496     
       
   497     // Using main menu width also for submenu(s), this
       
   498     // enables consistent scroll physics between main
       
   499     // menu and submenus 
       
   500     if ( iControl->iOwner )
       
   501         {       
       
   502         CEikMenuPane* menu = iControl->iOwner;
       
   503             
       
   504         // Go through sub menu hierarchy. There might be
       
   505         // multiple submenus, although default case is 
       
   506         // only one submenu.
       
   507         while ( menu->iOwner )
       
   508             {
       
   509             CEikMenuPane* prevMenu( menu );
       
   510             menu = menu->iOwner;
       
   511 
       
   512             // This prevents infinite loop if iOwner is equal to menu.
       
   513             if ( menu == prevMenu )
       
   514                 {
       
   515                 break;
       
   516                 }
       
   517             }
       
   518                             
       
   519         totalSize = TSize( menu->Rect().Width(), totalItemHeight );
       
   520         viewSize = TSize( menu->Rect().Width(), iViewHeight );      
       
   521         }
       
   522     
       
   523     iPhysics->InitPhysicsL( totalSize, viewSize, EFalse );
       
   524                                                             
       
   525     iViewPosition = TPoint( rect.Width() / 2, iListTopIndex + iViewHeight / 2 );
       
   526     _AKNTRACE( "totalSize(%d, %d)", totalSize.iWidth, totalSize.iHeight );
       
   527     _AKNTRACE( "viewSize(%d, %d)", viewSize.iWidth, viewSize.iHeight );
       
   528     _AKNTRACE( "iViewPosition(%d, %d)", iViewPosition.iX, iViewPosition.iY );
       
   529     _AKNTRACE_FUNC_EXIT;
       
   530     }
       
   531 
       
   532 
       
   533 // ---------------------------------------------------------------------------
       
   534 // Physics emulation has moved the view.
       
   535 // ---------------------------------------------------------------------------
       
   536 //
       
   537 void CEikMenuPaneExtension::ViewPositionChanged( const TPoint& aNewPosition,
       
   538                                                  TBool aDrawNow,
       
   539                                                  TUint /*aFlags*/ )
       
   540     {  
       
   541     _AKNTRACE_FUNC_ENTER;
       
   542     if ( !iControl->iItemArray )
       
   543         {
       
   544         return;
       
   545         }
       
   546     
       
   547     iListTopIndex = aNewPosition.iY - iViewHeight / 2;  
       
   548     
       
   549     iListBottomIndex = aNewPosition.iY + iViewHeight - iViewHeight / 2;
       
   550     
       
   551     TInt delta = iViewPosition.iY - aNewPosition.iY;
       
   552     
       
   553     DoOffset( delta );
       
   554 
       
   555     iViewPosition = aNewPosition; 
       
   556     _AKNTRACE( "iListTopIndex = %d",  iListTopIndex );
       
   557     _AKNTRACE( "iListBottomIndex = %d",  iListBottomIndex );
       
   558     _AKNTRACE( "delta = %d",  delta );
       
   559     _AKNTRACE( "iViewPosition(%d,%d)",  iViewPosition.iX, iViewPosition.iY );
       
   560     
       
   561     if ( aDrawNow )
       
   562         {
       
   563         TRAP_IGNORE( iControl->DoUpdateScrollBarL() );
       
   564 
       
   565         if ( iControl->iOwner ) // Submenu
       
   566             {
       
   567             iControl->DrawNow();
       
   568             }
       
   569         else
       
   570             {
       
   571             iControl->DrawNow( TRect( iMenuPaneRect.Size() ) );
       
   572             }        
       
   573         }
       
   574     _AKNTRACE_FUNC_EXIT;
       
   575     }
       
   576 
       
   577 
       
   578 void CEikMenuPaneExtension::DoOffset( TInt aOffset )
       
   579     {                                      
       
   580     _AKNTRACE_FUNC_ENTER;
       
   581     TInt itemsInRect = iControl->NumberOfItemsThatFitInView();
       
   582     TInt bottomListPosition = 0;
       
   583     
       
   584     if(iControl->iItemArray->Count() > itemsInRect)
       
   585         {
       
   586         bottomListPosition = (iControl->iItemArray->Count() - itemsInRect) * iControl->iItemHeight;
       
   587         }
       
   588     
       
   589     TInt itemIndex = iListTopIndex;
       
   590     
       
   591     if ( iListTopIndex <= 0 )
       
   592         {
       
   593         itemIndex = 0;                                
       
   594         } 
       
   595         
       
   596     else if ( iListTopIndex >= bottomListPosition )
       
   597         {
       
   598         itemIndex = bottomListPosition; 
       
   599         }           
       
   600     
       
   601     // Calculate new top item index                                                
       
   602     TInt newTopItemIndex = itemIndex / iControl->iItemHeight;
       
   603      
       
   604     // Calculate panning offset
       
   605     SetOffset( newTopItemIndex * iControl->iItemHeight - iListTopIndex );
       
   606      
       
   607     _AKNTRACE( " iVerticalOffset = %d",  iVerticalOffset );
       
   608     if ( newTopItemIndex >= 0 && newTopItemIndex < iControl->iItemArray->Count() )
       
   609         {
       
   610         _AKNTRACE( "%s", "iControl->iScroller->SetTopItemIndex(newTopItemIndex);" );
       
   611         iControl->iScroller->SetTopItemIndex(newTopItemIndex);
       
   612         }
       
   613     // calculate new top item index and offset
       
   614     TInt menuTopItemIndex = iListTopIndex/iControl->iItemHeight;
       
   615     
       
   616     TInt listBottomLimit = iControl->iItemArray->Count()* iControl->iItemHeight;
       
   617     
       
   618     if ( menuTopItemIndex > iControl->iItemArray->Count() )
       
   619     	{
       
   620     	menuTopItemIndex = iControl->iItemArray->Count() - 1;
       
   621     	}
       
   622     
       
   623     if ( menuTopItemIndex != iLastFeedbackTopItemIndex )
       
   624         {   
       
   625         iLastFeedbackTopItemIndex = menuTopItemIndex;
       
   626         // If the top list item index has changed, that means that there's
       
   627         // a new list item in view and thus feedback needs to be given
       
   628         // in case there's flicking or panning ongoing and not doing
       
   629         // bounce action
       
   630         if ( iFlickActive || iPanningActive )
       
   631             {
       
   632             if ( ( aOffset>0 && iListTopIndex <= listBottomLimit && iListTopIndex >= -iViewHeight ) ||
       
   633             	  ( aOffset<0 && iListBottomIndex >= 0 && iListBottomIndex <= listBottomLimit+iViewHeight ) ) 
       
   634             	{
       
   635             	if ( iPhysics )
       
   636                     {
       
   637                     TTouchFeedbackType feedbackType = ETouchFeedbackVibra;
       
   638                     switch( iPhysics->OngoingPhysicsAction() )
       
   639                         {
       
   640                         case CAknPhysics::EAknPhysicsActionDragging:
       
   641                             {
       
   642                             feedbackType = static_cast<TTouchFeedbackType> ( ETouchFeedbackVibra | ETouchFeedbackAudio );
       
   643                             }
       
   644                         case CAknPhysics::EAknPhysicsActionFlicking:
       
   645                         case CAknPhysics::EAknPhysicsActionBouncing:
       
   646                             {
       
   647                             ImmediateFeedback( ETouchFeedbackSensitiveList,
       
   648                                                feedbackType );
       
   649                             break;
       
   650                             }
       
   651                         default:
       
   652                             break;
       
   653                         }
       
   654                     }
       
   655             	}
       
   656             }
       
   657         }
       
   658     _AKNTRACE_FUNC_EXIT;
       
   659     }
       
   660 
       
   661 void CEikMenuPaneExtension::RestoreOffset( TInt aKeyCode )
       
   662     {    
       
   663     if ( aKeyCode == 0 )
       
   664         {
       
   665         return;
       
   666         }
       
   667     _AKNTRACE_FUNC_ENTER;    
       
   668     TPoint oldViewPos = iViewPosition;
       
   669     
       
   670     TInt itemsInRect = iControl->NumberOfItemsThatFitInView();
       
   671     TInt topItem = iControl->iScroller->TopItemIndex();
       
   672     TInt bottomItem = topItem + itemsInRect;
       
   673     TInt highLightItem = iControl->iSelectedItem;    
       
   674            
       
   675     // There is partially visible items in menu. Offset is restored here if highlight 
       
   676     // is moved to partially visible item by using hw keys (up/down)     
       
   677     if ( ( highLightItem == topItem + 1 || highLightItem == topItem ) 
       
   678         && aKeyCode == EKeyUpArrow )
       
   679         {   
       
   680         iViewPosition.iY += iVerticalOffset;
       
   681         }
       
   682     //ENothingSelected is for sct row.
       
   683     else if ( ( highLightItem == bottomItem - 1 
       
   684                 || highLightItem == bottomItem
       
   685                 || highLightItem == CEikMenuPane::ENothingSelected                
       
   686               ) && aKeyCode == EKeyDownArrow )
       
   687         {
       
   688         iViewPosition.iY += iControl->iItemHeight + iVerticalOffset;
       
   689         }        
       
   690     // Submenu can be opened with left or right key depending on layout 
       
   691     // or with selection keys   
       
   692     else if ( ( !AknLayoutUtils::LayoutMirrored() && aKeyCode == EKeyRightArrow ) ||
       
   693               ( AknLayoutUtils::LayoutMirrored() && aKeyCode == EKeyLeftArrow ) ||
       
   694                 aKeyCode == EKeyEnter || aKeyCode == EKeyOK || aKeyCode == EAknSoftkeyOk ||
       
   695                 aKeyCode == EAknSoftkeySelect || aKeyCode == EAknSoftkeyOk )
       
   696         {
       
   697         if ( highLightItem != CEikMenuPane::ENothingSelected )
       
   698             {
       
   699             const CEikMenuPaneItem* item = (*iControl->iItemArray)[highLightItem];
       
   700             // Check if item has submenu                
       
   701             if ( item->iData.iCascadeId )
       
   702                 {
       
   703                 // Submenu is going to be opened from partial item, we need
       
   704                 // to bring it fully visible
       
   705                 if ( highLightItem == topItem )
       
   706                     {   
       
   707                     iViewPosition.iY += iVerticalOffset;
       
   708                     }
       
   709                 else if ( highLightItem == bottomItem )
       
   710                     {
       
   711                     iViewPosition.iY += iControl->iItemHeight + iVerticalOffset;
       
   712                     }             
       
   713                 }             
       
   714             }     
       
   715         }
       
   716 
       
   717     // Avoid redraw if position not changed
       
   718     if ( oldViewPos != iViewPosition )
       
   719         {
       
   720         // Report view position change to scroll physics
       
   721         // when sub menu is opened with hw keys.                                            
       
   722         _AKNTRACE( "[%s]", " ViewPositionChanged( iViewPosition )" );
       
   723         ViewPositionChanged( iViewPosition );
       
   724         }
       
   725     _AKNTRACE_FUNC_EXIT;
       
   726     }
       
   727 
       
   728 void CEikMenuPaneExtension::SetOffset( TInt aOffset )
       
   729     {   
       
   730     iVerticalOffset = aOffset;
       
   731     _AKNTRACE( "iVerticalOffset = %d", iVerticalOffset );
       
   732     }
       
   733 
       
   734 
       
   735 void CEikMenuPaneExtension::PhysicEmulationEnded()
       
   736     {
       
   737     _AKNTRACE_FUNC_ENTER;    
       
   738     iFlickActive = EFalse; 
       
   739 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   740     MAknListBoxTfx* tfxApi = CAknListLoader::TfxApi( iGc );
       
   741 
       
   742     if ( tfxApi )
       
   743         {
       
   744         tfxApi->EnableEffects( ETrue );
       
   745         }
       
   746 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
   747     _AKNTRACE_FUNC_EXIT;
       
   748     }    
       
   749     
       
   750 TPoint CEikMenuPaneExtension::ViewPosition() const
       
   751     {
       
   752     _AKNTRACE( "iViewPosition(%d,%d)",  iViewPosition.iX, iViewPosition.iY );
       
   753     return iViewPosition;
       
   754     }    
       
   755 //
       
   756 // =============================================================================
       
   757 // Helper class that monitor redirection changes declaration & definition
       
   758 // =============================================================================
       
   759 /*
       
   760  * CRedirectionListener
       
   761  *
       
   762  * Delays opening of submenus during appear transitions
       
   763  */
       
   764 NONSHARABLE_CLASS( CRedirectionListener ) : public CBase,
       
   765                                             public MAknTransitionUtilsObserver
       
   766     {
       
   767 public:
       
   768     CRedirectionListener( CEikMenuPaneExtension& aOwner );
       
   769     ~CRedirectionListener();
       
   770 
       
   771     void AppearTransitionStarting();
       
   772     void Closing();
       
   773     void LaunchCascadeMenu();
       
   774 private:
       
   775     TInt AknTransitionCallback( TInt aEvent, TInt aState,
       
   776                                 const TDesC8* /*aParams*/ );
       
   777 private: // Data
       
   778     TBool iObserving;
       
   779     TBool iTransitionUpcoming;
       
   780     TBool iAppearTransitionRunning;
       
   781     TBool iLaunchWhenUnredirected;
       
   782     CEikMenuPaneExtension& iOwner;
       
   783     };
       
   784 
       
   785 // -----------------------------------------------------------------------------
       
   786 // CRedirectionListener::CRedirectionListener
       
   787 // -----------------------------------------------------------------------------
       
   788 //
       
   789 CRedirectionListener::CRedirectionListener( CEikMenuPaneExtension& aOwner ) :
       
   790     iOwner( aOwner )
       
   791     {
       
   792     }
       
   793 
       
   794 // -----------------------------------------------------------------------------
       
   795 // CRedirectionListener::~CRedirectionListener
       
   796 // -----------------------------------------------------------------------------
       
   797 //
       
   798 CRedirectionListener::~CRedirectionListener()
       
   799     {
       
   800     Closing();
       
   801     }
       
   802 
       
   803 // -----------------------------------------------------------------------------
       
   804 // CRedirectionListener::AppearTransitionStarting
       
   805 // -----------------------------------------------------------------------------
       
   806 //
       
   807 void CRedirectionListener::AppearTransitionStarting()
       
   808     {
       
   809     TInt err = KErrNone;
       
   810     iAppearTransitionRunning = EFalse;
       
   811     if ( !iObserving )
       
   812         {
       
   813         err = CAknTransitionUtils::AddObserver( this,
       
   814                             CAknTransitionUtils::EEventWsBufferRedirection );
       
   815         }
       
   816     // Only set this value if observing
       
   817     if ( err == KErrNone )
       
   818         {
       
   819         iObserving = ETrue;
       
   820         iTransitionUpcoming = ETrue;
       
   821         }
       
   822     }
       
   823 
       
   824 // -----------------------------------------------------------------------------
       
   825 // CRedirectionListener::Closing
       
   826 // -----------------------------------------------------------------------------
       
   827 //
       
   828 void CRedirectionListener::Closing()
       
   829     {
       
   830     if ( iObserving )
       
   831         {
       
   832         CAknTransitionUtils::RemoveObserver( this,
       
   833                             CAknTransitionUtils::EEventWsBufferRedirection );
       
   834         iObserving = EFalse;
       
   835         }
       
   836     iTransitionUpcoming = EFalse;
       
   837     iLaunchWhenUnredirected = EFalse;
       
   838     }
       
   839 
       
   840 // -----------------------------------------------------------------------------
       
   841 // CRedirectionListener::LaunchCascadeMenuL
       
   842 // -----------------------------------------------------------------------------
       
   843 //
       
   844 void CRedirectionListener::LaunchCascadeMenu()
       
   845     {
       
   846     if ( iTransitionUpcoming && iObserving )
       
   847         {
       
   848         // Get current redirection status
       
   849         TInt redirected;
       
   850         TInt err = RProperty::Get( KPSUidAvkonDomain,
       
   851                                    KAknTfxServerRedirectionStatus,
       
   852                         redirected );
       
   853         
       
   854         if ( err == KErrNone && redirected )
       
   855             {
       
   856             // Transition has started
       
   857             iAppearTransitionRunning = ETrue;
       
   858             }
       
   859         }
       
   860     
       
   861     if ( iAppearTransitionRunning )
       
   862         {
       
   863         // Lauch submenu when unredireted if currently in transition
       
   864         iLaunchWhenUnredirected = ETrue;
       
   865         }
       
   866     else
       
   867         {
       
   868         // Launch submenu imediately if not currently in transition
       
   869         iOwner.StartCascadeMenuAppearTransition();
       
   870         iLaunchWhenUnredirected = EFalse;
       
   871         }
       
   872     }
       
   873 
       
   874 // -----------------------------------------------------------------------------
       
   875 // CRedirectionListener::AknTransitionCallback
       
   876 // -----------------------------------------------------------------------------
       
   877 //
       
   878 TInt CRedirectionListener::AknTransitionCallback( TInt aEvent, TInt aState,
       
   879                             const TDesC8* /*aParams*/ )
       
   880     {
       
   881     if ( aEvent == CAknTransitionUtils::EEventWsBufferRedirection )
       
   882         {
       
   883         if ( aState)
       
   884             {
       
   885             // Redirected (transition started)
       
   886             // Don't display submenu until unredirected
       
   887             iAppearTransitionRunning = iTransitionUpcoming;
       
   888             }
       
   889         else
       
   890             {
       
   891             // Unredirected (transition finished)
       
   892             iAppearTransitionRunning = EFalse;
       
   893             if ( iLaunchWhenUnredirected )
       
   894                 {
       
   895                 // Launch submenu waiting to be opened
       
   896                 iOwner.StartCascadeMenuAppearTransition();
       
   897                 iLaunchWhenUnredirected = EFalse;
       
   898                 }
       
   899             }
       
   900         iTransitionUpcoming = EFalse;
       
   901         }
       
   902     return 0;
       
   903     }
       
   904 
       
   905 // -----------------------------------------------------------------------------
       
   906 // CEikMenuPaneExtension::StartCascadeMenuAppearTransition
       
   907 // -----------------------------------------------------------------------------
       
   908 //
       
   909 void CEikMenuPaneExtension::StartCascadeMenuAppearTransition()
       
   910     {
       
   911     CEikMenuPane* cascadeMenuPane = iControl->iCascadeMenuPane;
       
   912     if ( cascadeMenuPane )
       
   913         {
       
   914         cascadeMenuPane->SetParent( iControl );
       
   915         GfxTransEffect::Begin( cascadeMenuPane, KGfxControlAppearAction );
       
   916         cascadeMenuPane->StartDisplayingMenuPane( iControl->iHotKeyTable,
       
   917                                                   iControl->Position(),
       
   918                                                   NULL,
       
   919                                                   0,
       
   920                                                   EPopupTargetBottomLeft );
       
   921 
       
   922         GfxTransEffect::SetDemarcation( cascadeMenuPane, iCascadeDRect );
       
   923         GfxTransEffect::End( cascadeMenuPane );
       
   924 
       
   925         // Transfer focus to cascade menu (highlight animations adapt to focus
       
   926         // change)
       
   927         cascadeMenuPane->SetFocus( ETrue, EDrawNow );
       
   928         iControl->SetFocus( EFalse, EDrawNow );
       
   929         }
       
   930     }
       
   931 
       
   932 // -----------------------------------------------------------------------------
       
   933 // CEikMenuPaneExtension::CEikMenuPaneExtension
       
   934 // High CActive priority is well argumented because running the active object
       
   935 // will result in animation deletion -> results in freeing resources.
       
   936 // -----------------------------------------------------------------------------
       
   937 //
       
   938 CEikMenuPaneExtension::CEikMenuPaneExtension() :
       
   939     CActive( EPriorityHigh ),
       
   940     // Initialise data members to zero
       
   941     iCascadeBitmap( NULL ),
       
   942     iCascadeBitmapMask( NULL ),
       
   943     iBgContext( NULL ),
       
   944     iSubMenuWidthIndex( 1 ),
       
   945     iCheckMarkBitmap( NULL ),
       
   946     iCheckMarkBitmapMask( NULL ),
       
   947     iRadioButtonBitmap( NULL ),
       
   948     iRadioButtonBitmapMask( NULL ),
       
   949     iHasRadioGroup( EFalse ),
       
   950     iSelectedRadioButtonItem( KNoSelectedRadioButtonItem ),
       
   951     iGrabbingCBAComponent( NULL ),
       
   952     iControl( NULL ),
       
   953     iAnimation( NULL ),
       
   954     iAnimFlags ( 0 ),
       
   955     iSct( NULL ),
       
   956     iSctHighlighted( EFalse ),
       
   957     iSpecialCharPointed( EFalse )
       
   958 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   959     ,iGc ( NULL )
       
   960 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
   961     ,iVerticalOffset( 0 )
       
   962     ,iPhysics( NULL )
       
   963     ,iListTopIndex( 0 )
       
   964     ,iViewHeight( 0 )
       
   965     ,iFlickActive( EFalse )
       
   966     ,iPanningActive( EFalse )
       
   967     ,iFeedback( MTouchFeedback::Instance() )
       
   968     ,iLastFeedbackTopItemIndex( 0 )
       
   969     {
       
   970     iIsPenEnable = AknLayoutUtils::PenEnabled();
       
   971     iItemsReadyForPenSelection = !iIsPenEnable;
       
   972     iNextHighlightItem = KErrNotFound;
       
   973     }
       
   974 
       
   975 // -----------------------------------------------------------------------------
       
   976 // CEikMenuPaneExtension::~CEikMenuPaneExtension
       
   977 // Destructor for extension class
       
   978 // -----------------------------------------------------------------------------
       
   979 //
       
   980 CEikMenuPaneExtension::~CEikMenuPaneExtension()
       
   981     {
       
   982     _AKNTRACE_FUNC_ENTER;
       
   983 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   984     if ( CAknListLoader::TfxApiInternal( iGc ) )
       
   985         {
       
   986         delete iGc;
       
   987         }
       
   988 #endif
       
   989     Cancel(); // Cancel possibly pending request
       
   990 
       
   991     // Stop receiving foreground events
       
   992     CCoeEnv* env = CCoeEnv::Static();
       
   993     env->RemoveForegroundObserver( *this );
       
   994 
       
   995     delete iCascadeBitmap;
       
   996     iCascadeBitmap = NULL;
       
   997 
       
   998     delete iCascadeBitmapMask;
       
   999     iCascadeBitmapMask = NULL;
       
  1000 
       
  1001     delete iBgContext;
       
  1002     iBgContext = NULL;
       
  1003 
       
  1004     delete iCheckMarkBitmap;
       
  1005     iCheckMarkBitmap = NULL;
       
  1006 
       
  1007     delete iCheckMarkBitmapMask;
       
  1008     iCheckMarkBitmapMask = NULL;
       
  1009 
       
  1010     delete iRadioButtonBitmap;
       
  1011     iRadioButtonBitmap = NULL;
       
  1012 
       
  1013     delete iRadioButtonBitmapMask;
       
  1014     iRadioButtonBitmapMask = NULL;
       
  1015 
       
  1016     iControl = NULL;
       
  1017 
       
  1018     delete iAnimation;
       
  1019     iAnimation = NULL;
       
  1020 
       
  1021     delete iSct;
       
  1022     iSct = NULL;
       
  1023 
       
  1024     delete iCascadeMenuObject;
       
  1025     iCascadeMenuObject = NULL;
       
  1026 
       
  1027     delete iTimer;
       
  1028     iTimer = NULL;
       
  1029     
       
  1030     delete iHighlightTimer;
       
  1031     iHighlightTimer = NULL;
       
  1032 
       
  1033     if ( iTaskSwapIdle )
       
  1034         {
       
  1035         if ( iTaskSwapIdle->IsActive() )
       
  1036             {
       
  1037             iTaskSwapIdle->Cancel();
       
  1038             TaskSwapCallBack( NULL );
       
  1039             }
       
  1040         delete iTaskSwapIdle;
       
  1041         }
       
  1042 
       
  1043     delete iRedirectionListener;
       
  1044     delete iPhysics;
       
  1045     _AKNTRACE_FUNC_EXIT;
       
  1046     }
       
  1047 
       
  1048 // -----------------------------------------------------------------------------
       
  1049 // CEikMenuPaneExtension::ConstructL
       
  1050 // -----------------------------------------------------------------------------
       
  1051 //
       
  1052 void CEikMenuPaneExtension::ConstructL( CEikMenuPane* aControl )
       
  1053     {
       
  1054     ASSERT( aControl );
       
  1055     iControl = aControl;
       
  1056     iAnimFlags.Set( EFlagUseAnimation ); // Animations are created by default
       
  1057     CActiveScheduler::Add( this );
       
  1058     iDraggedOutside = EFalse;
       
  1059     iLaunchCascadeMenu = EFalse;
       
  1060     iButtonDownItem = KErrNotFound;
       
  1061     iTaskSwapIdle = CIdle::NewL( CActive::EPriorityHigh );
       
  1062     if ( aControl->iOwner == NULL && GfxTransEffect::IsRegistered( aControl ) )
       
  1063         {
       
  1064         // Delays submenu opening during appear transitions
       
  1065         iRedirectionListener = new ( ELeave ) CRedirectionListener( *this );
       
  1066         }
       
  1067 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  1068         iGc = CAknListLoader::CreateTfxGc( *aControl,
       
  1069                                            iControl->iScroller->iTopItemIndex,
       
  1070                                            iTotalNumberOfItemsInView );
       
  1071 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  1072     if ( static_cast<CAknAppUi*>(
       
  1073             iControl->ControlEnv()->AppUi() )->IsSingleClickCompatible() )
       
  1074         {
       
  1075         iFlags.Set( ESingleClickEnabled );
       
  1076         }
       
  1077 
       
  1078     if ( !iPhysics )
       
  1079         {
       
  1080         iPhysics = CAknPhysics::NewL( *this, iControl );
       
  1081         }
       
  1082     
       
  1083     iBgContext = CAknsFrameBackgroundControlContext::NewL(
       
  1084         KAknsIIDQsnFrPopup, TRect( 0, 0, 1, 1 ), TRect( 0, 0, 1, 1 ), EFalse );
       
  1085     }
       
  1086 
       
  1087 // -----------------------------------------------------------------------------
       
  1088 // CEikMenuPaneExtension::CreateAnimation
       
  1089 // -----------------------------------------------------------------------------
       
  1090 //
       
  1091 void CEikMenuPaneExtension::CreateAnimation()
       
  1092     {
       
  1093 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  1094     return;
       
  1095 #else    
       
  1096     if( !iAnimation && iAnimFlags.IsSet( EFlagUseAnimation ) )
       
  1097         {    
       
  1098         TRect rect = iControl->HighlightRect();
       
  1099         TRAPD( err, CreateAnimationL( rect.Size() ) );
       
  1100         if( KErrNone != err )
       
  1101             {
       
  1102             // Animation has not been drawn -> no need for repaint
       
  1103             UseNoAnimation();
       
  1104             }
       
  1105         }
       
  1106 #endif //RD_UI_TRANSITION_EFFECTS_LIST  
       
  1107     }
       
  1108 
       
  1109 // -----------------------------------------------------------------------------
       
  1110 // CEikMenuPaneExtension::NoAnimIfError
       
  1111 // -----------------------------------------------------------------------------
       
  1112 //
       
  1113 void CEikMenuPaneExtension::NoAnimIfError( TInt aError )
       
  1114     {
       
  1115     if( KErrNone != aError )
       
  1116         UseNoAnimation();
       
  1117     }
       
  1118 
       
  1119 // -----------------------------------------------------------------------------
       
  1120 // CEikMenuPaneExtension::UseNoAnimation
       
  1121 // Falls back to normal highlight rendering.
       
  1122 // -----------------------------------------------------------------------------
       
  1123 //
       
  1124 void CEikMenuPaneExtension::UseNoAnimation()
       
  1125     {
       
  1126     delete iAnimation;
       
  1127     iAnimation = NULL;
       
  1128 
       
  1129     // Do not attempt to create animations in the future
       
  1130     iAnimFlags.Clear( EFlagUseAnimation );
       
  1131 
       
  1132     // Stop receiving foreground events
       
  1133     CCoeEnv* env = CCoeEnv::Static();
       
  1134     env->RemoveForegroundObserver( *this );
       
  1135     }
       
  1136 
       
  1137 // -----------------------------------------------------------------------------
       
  1138 // CEikMenuPaneExtension::StartCascadeMenuTimerL
       
  1139 // Starts the timer for the sub menu launch. Timer is constructed when used for
       
  1140 // the first time
       
  1141 // -----------------------------------------------------------------------------
       
  1142 //
       
  1143 void CEikMenuPaneExtension::StartCascadeMenuTimerL()
       
  1144     {
       
  1145     _AKNTRACE_FUNC_ENTER;
       
  1146     if ( !iTimer )
       
  1147         {
       
  1148         iTimer = CPeriodic::NewL( CActive::EPriorityStandard );
       
  1149         }
       
  1150     else if ( iTimer->IsActive() )
       
  1151         {
       
  1152         iTimer->Cancel();
       
  1153         }
       
  1154     iTimer->Start( KCascadeMenuOpenDelay,
       
  1155                    KCascadeMenuOpenDelay,
       
  1156                    TCallBack ( CascadeMenuTimerCallBack, this ) );
       
  1157     _AKNTRACE_FUNC_EXIT;
       
  1158     }
       
  1159 
       
  1160 // -----------------------------------------------------------------------------
       
  1161 // CEikMenuPaneExtension::StopCascadeMenuTimer
       
  1162 // Stops the timer for the sub menu launch
       
  1163 // -----------------------------------------------------------------------------
       
  1164 //    
       
  1165 void CEikMenuPaneExtension::StopCascadeMenuTimer()
       
  1166     {
       
  1167     _AKNTRACE_FUNC_ENTER;
       
  1168     if ( iTimer && iTimer->IsActive() )
       
  1169         {
       
  1170         iTimer->Cancel();
       
  1171         }
       
  1172     iLaunchCascadeMenu = EFalse;
       
  1173     _AKNTRACE_FUNC_EXIT;
       
  1174     }
       
  1175 
       
  1176 // -----------------------------------------------------------------------------
       
  1177 // CEikMenuPaneExtension::CascadeMenuTimerCallBack
       
  1178 // Callback function of the timer for the sub menu launch
       
  1179 // -----------------------------------------------------------------------------
       
  1180 //    
       
  1181 TInt CEikMenuPaneExtension::CascadeMenuTimerCallBack( TAny* aThis )
       
  1182     {
       
  1183     _AKNTRACE_FUNC_ENTER;
       
  1184     CEikMenuPaneExtension* self = 
       
  1185         reinterpret_cast <CEikMenuPaneExtension*> ( aThis );
       
  1186     self->iLaunchCascadeMenu = ETrue;
       
  1187     _AKNTRACE_FUNC_EXIT;
       
  1188     return KErrNone;
       
  1189     }
       
  1190 
       
  1191 // -----------------------------------------------------------------------------
       
  1192 // CEikMenuPaneExtension::IsCascadeMenuTimerActive
       
  1193 // Returns ETrue if timer is active 
       
  1194 // -----------------------------------------------------------------------------
       
  1195 //    
       
  1196 TBool CEikMenuPaneExtension::IsCascadeMenuTimerActive()
       
  1197     {
       
  1198     if ( !iTimer )
       
  1199         {
       
  1200         return EFalse;
       
  1201         }
       
  1202     return iTimer->IsActive();
       
  1203     }
       
  1204 
       
  1205 
       
  1206 // -----------------------------------------------------------------------------
       
  1207 // CEikMenuPaneExtension::StartHighlightTimerL
       
  1208 // Starts the timer for the pressed down highlight activation.
       
  1209 // Timer is constructed when used for the first time
       
  1210 // -----------------------------------------------------------------------------
       
  1211 //
       
  1212 void CEikMenuPaneExtension::StartHighlightTimerL()
       
  1213     {
       
  1214     _AKNTRACE_FUNC_ENTER;
       
  1215     if ( !iHighlightTimer )
       
  1216         {
       
  1217         iHighlightTimer = CPeriodic::NewL( CActive::EPriorityStandard );
       
  1218         if ( !iHighlightTimer )
       
  1219             {
       
  1220             return;
       
  1221             }
       
  1222         }
       
  1223     else if ( iHighlightTimer->IsActive() )
       
  1224         {
       
  1225         iHighlightTimer->Cancel();
       
  1226         }
       
  1227         
       
  1228     TInt timeout ( 0 );
       
  1229     if ( iPhysics )
       
  1230         {
       
  1231         timeout = iPhysics->HighlightTimeout() * 1000;
       
  1232         }
       
  1233     iPressedDown = EFalse;        
       
  1234     iHighlightTimer->Start( timeout,timeout, 
       
  1235                    TCallBack ( HighlightTimerCallBack, this ) );
       
  1236     _AKNTRACE_FUNC_EXIT;
       
  1237     }
       
  1238 
       
  1239 
       
  1240 // ---------------------------------------------------------------------------
       
  1241 // CEikMenuPaneExtension::ResetPressedHighlight
       
  1242 // Stops the timer for the pressed down highlight activation and resets the
       
  1243 // pressed highlight
       
  1244 // ---------------------------------------------------------------------------
       
  1245 //    
       
  1246 void CEikMenuPaneExtension::ResetPressedHighlight()
       
  1247     {
       
  1248     _AKNTRACE_FUNC_ENTER;
       
  1249     if ( HighlightTimerActive() )
       
  1250         {
       
  1251         iHighlightTimer->Cancel();
       
  1252         }
       
  1253 
       
  1254     // if status changed repaint needed    
       
  1255     if ( iPressedDown )
       
  1256         {
       
  1257         iPressedDown = EFalse;
       
  1258         iControl->RepaintHighlight();    
       
  1259         }
       
  1260     _AKNTRACE_FUNC_EXIT;
       
  1261     }
       
  1262 
       
  1263 // -----------------------------------------------------------------------------
       
  1264 // CEikMenuPaneExtension::HighlightTimerCallBack
       
  1265 // Callback function of the timer for pressed down highlight
       
  1266 // -----------------------------------------------------------------------------
       
  1267 //    
       
  1268 TInt CEikMenuPaneExtension::HighlightTimerCallBack( TAny* aThis )
       
  1269     {
       
  1270     _AKNTRACE_FUNC_ENTER;
       
  1271     CEikMenuPaneExtension* self = 
       
  1272         reinterpret_cast <CEikMenuPaneExtension*> ( aThis );
       
  1273     self->iPressedDown = ETrue;
       
  1274     if ( self->iControl->SelectedItem() == self->iNextHighlightItem )
       
  1275         {
       
  1276         self->iControl->RepaintHighlight();
       
  1277         }
       
  1278     else
       
  1279         {
       
  1280         if ( self->iNextHighlightItem != KErrNotFound )
       
  1281             {
       
  1282             self->iControl->MoveHighlightTo( self->iNextHighlightItem );
       
  1283             }
       
  1284         }
       
  1285     self->iNextHighlightItem = KErrNotFound;
       
  1286     if ( self->HighlightTimerActive() )
       
  1287         {
       
  1288         self->iHighlightTimer->Cancel();
       
  1289         }
       
  1290     _AKNTRACE_FUNC_EXIT;
       
  1291     return KErrNone;
       
  1292     }
       
  1293 
       
  1294 
       
  1295 // ---------------------------------------------------------------------------
       
  1296 // Checks if the highlight timer is running.
       
  1297 // ---------------------------------------------------------------------------
       
  1298 //
       
  1299 TBool CEikMenuPaneExtension::HighlightTimerActive() const
       
  1300     {
       
  1301     return ( iHighlightTimer && iHighlightTimer->IsActive() );
       
  1302     }
       
  1303 
       
  1304 
       
  1305 // -----------------------------------------------------------------------------
       
  1306 // CEikMenuPaneExtension::ChangePosition
       
  1307 // Position of aPointerEvent should be modified when point in beside scrollbar.
       
  1308 // -----------------------------------------------------------------------------
       
  1309 //
       
  1310 void CEikMenuPaneExtension::ChangePosition( TPointerEvent& aPointerEvent )    
       
  1311     {
       
  1312     if ( !iControl->iSBFrame )
       
  1313         {
       
  1314         iControl->CreateScrollBarFrame();
       
  1315         }
       
  1316     TRect scrollBarRect = iControl->iSBFrame->VerticalScrollBar()->Rect();
       
  1317     TPoint scrollerTl = scrollBarRect.iTl; 
       
  1318     TPoint scrollerBr = scrollBarRect.iBr;
       
  1319     TRect gapRect;           
       
  1320     // For layout that left to right
       
  1321     if ( !AknLayoutUtils::LayoutMirrored() )
       
  1322         {
       
  1323         TPoint rectTl( scrollerBr.iX, iControl->Rect().iTl.iY );
       
  1324         gapRect.SetRect( rectTl, iControl->Rect().iBr );
       
  1325         }
       
  1326     // For layout that right to left
       
  1327     else
       
  1328         {
       
  1329         TPoint rectBr( scrollerTl.iX, iControl->Rect().iBr.iY );
       
  1330         gapRect.SetRect( iControl->Rect().iTl, rectBr );         
       
  1331         } 
       
  1332        
       
  1333     if ( gapRect.Contains( aPointerEvent.iPosition ) )
       
  1334         {
       
  1335         if ( !AknLayoutUtils::LayoutMirrored() )
       
  1336             {
       
  1337             aPointerEvent.iPosition.iX = scrollerBr.iX - 1;
       
  1338             }
       
  1339         else
       
  1340             {
       
  1341             aPointerEvent.iPosition.iX = scrollerTl.iX;
       
  1342             }        
       
  1343         //Modify y coordinate of point in top left/right corner of options menu
       
  1344         if ( aPointerEvent.iPosition.iY < scrollerTl.iY )
       
  1345             {
       
  1346             aPointerEvent.iPosition.iY = scrollerTl.iY;
       
  1347             }            
       
  1348         //Modify y coordinate of point in bottom left/right corner of options menu
       
  1349         if ( aPointerEvent.iPosition.iY > scrollerBr.iY )
       
  1350             {
       
  1351             aPointerEvent.iPosition.iY = scrollerBr.iY - 1;
       
  1352             }
       
  1353         }       
       
  1354     }
       
  1355 
       
  1356 
       
  1357 // -----------------------------------------------------------------------------
       
  1358 // CEikMenuPaneExtension::CalculateParentEvent
       
  1359 // Calculate parent event for sub menu.
       
  1360 // -----------------------------------------------------------------------------
       
  1361 //
       
  1362 void CEikMenuPaneExtension::CalculateParentEvent( const TPointerEvent& aPointerEvent, 
       
  1363                            TPointerEvent& aParentEvent )
       
  1364     {
       
  1365     aParentEvent.iModifiers = aPointerEvent.iModifiers;
       
  1366     TPoint subPos = iControl->PositionRelativeToScreen();
       
  1367     TPoint ownerPos = iControl->iOwner->PositionRelativeToScreen();
       
  1368     aParentEvent.iPosition.SetXY (
       
  1369         aPointerEvent.iPosition.iX + subPos.iX - ownerPos.iX,
       
  1370         aPointerEvent.iPosition.iY + subPos.iY - ownerPos.iY);
       
  1371     aParentEvent.iType = aPointerEvent.iType;    
       
  1372     }
       
  1373 
       
  1374 // -----------------------------------------------------------------------------
       
  1375 // CEikMenuPaneExtension::GetBackgroundRect
       
  1376 // Get background rect for landscape mode of menu pane.
       
  1377 // -----------------------------------------------------------------------------
       
  1378 //    
       
  1379 TRect CEikMenuPaneExtension::GetBackgroundRect( const TRect& aWindowRect ) const
       
  1380     {
       
  1381     return aWindowRect;
       
  1382     }
       
  1383         
       
  1384 // -----------------------------------------------------------------------------
       
  1385 // CEikMenuPaneExtension::AdjustPopupLayoutData
       
  1386 // Adjust popup layout data for main menu pane in landscape mode
       
  1387 // -----------------------------------------------------------------------------
       
  1388 // 
       
  1389 void CEikMenuPaneExtension::AdjustPopupLayoutData( TAknWindowLineLayout& aListScrollPaneLayout )
       
  1390     {
       
  1391     TRect screenRect;
       
  1392     AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EScreen, screenRect );
       
  1393     AknLayoutUtils::TAknCbaLocation cbaPosition = AknLayoutUtils::CbaLocation();
       
  1394 
       
  1395     if ( screenRect.Width() == EQhdWidth && screenRect.Height() == EQhdHeight 
       
  1396         && cbaPosition == AknLayoutUtils::EAknCbaLocationBottom ) 
       
  1397         {
       
  1398         if ( !AknLayoutUtils::LayoutMirrored() )
       
  1399             {
       
  1400             aListScrollPaneLayout.ir -= 32;
       
  1401             }
       
  1402         else
       
  1403             {
       
  1404             aListScrollPaneLayout.il -= 32;
       
  1405             }
       
  1406         }
       
  1407     } 
       
  1408 
       
  1409 
       
  1410 // -----------------------------------------------------------------------------
       
  1411 // CEikMenuPaneExtension::GetMenuItemTextLayout
       
  1412 // Get Layout of menu item text.
       
  1413 // -----------------------------------------------------------------------------
       
  1414 //
       
  1415 const TAknLayoutText CEikMenuPaneExtension::GetMenuItemTextLayout(const TRect& aItemRect, TBool cascade)
       
  1416     {
       
  1417     TAknTextLineLayout menuTextLayout;
       
  1418     
       
  1419     if ( !iControl->iOwner )
       
  1420         {
       
  1421         menuTextLayout = AknLayoutScalable_Avkon::list_single_pane_t1_cp2( cascade ? 3 : 0 ).LayoutLine();
       
  1422         }
       
  1423     else
       
  1424         {
       
  1425         if ( iHasIcon )
       
  1426             {
       
  1427             menuTextLayout = TAknTextLineLayout( AknLayoutScalable_Avkon::list_single_popup_submenu_pane_t1( 1 ).LayoutLine() );
       
  1428             }
       
  1429         else
       
  1430             {
       
  1431             menuTextLayout = TAknTextLineLayout( AknLayoutScalable_Avkon::list_single_popup_submenu_pane_t1( 0 ).LayoutLine() );
       
  1432             }
       
  1433         }
       
  1434     
       
  1435     TAknLayoutText textRect;
       
  1436     textRect.LayoutText( aItemRect, menuTextLayout );
       
  1437     return textRect;
       
  1438     }
       
  1439 
       
  1440 
       
  1441 // -----------------------------------------------------------------------------
       
  1442 // CEikMenuPaneExtension::FocusGained
       
  1443 // The owning control has gained focus -> animation should be continued.
       
  1444 // -----------------------------------------------------------------------------
       
  1445 //
       
  1446 void CEikMenuPaneExtension::FocusGained()
       
  1447     {
       
  1448     Play();
       
  1449     }
       
  1450 
       
  1451 // -----------------------------------------------------------------------------
       
  1452 // CEikMenuPaneExtension::FocusLost
       
  1453 // The owning control has lost focus -> no running animation (even if the
       
  1454 // control is partially visible).
       
  1455 // -----------------------------------------------------------------------------
       
  1456 //
       
  1457 void CEikMenuPaneExtension::FocusLost()
       
  1458     {
       
  1459     if( iAnimation )
       
  1460         {
       
  1461         NoAnimIfError( iAnimation->Pause() );
       
  1462         }
       
  1463     }
       
  1464 
       
  1465 // -----------------------------------------------------------------------------
       
  1466 // CEikMenuPaneExtension::HandleLayoutSwitch
       
  1467 // -----------------------------------------------------------------------------
       
  1468 //
       
  1469 void CEikMenuPaneExtension::HandleLayoutSwitch()
       
  1470     {
       
  1471     if( iAnimation ) // Animation exists -> try to resize
       
  1472         {
       
  1473         TRect rect( iControl->HighlightRect() );
       
  1474 
       
  1475         // Resize animation
       
  1476         TBool aboutToStart = ETrue;
       
  1477         if( iAnimation->State() == EAknsAnimStateStopped )
       
  1478             aboutToStart = EFalse;
       
  1479 
       
  1480         TRAPD( err, DoResizeL( rect.Size(), aboutToStart ) );
       
  1481         NoAnimIfError( err );
       
  1482         }
       
  1483     }
       
  1484 
       
  1485 // -----------------------------------------------------------------------------
       
  1486 // CEikMenuPaneExtension::ChangeHighlightBackground
       
  1487 // -----------------------------------------------------------------------------
       
  1488 //
       
  1489 void CEikMenuPaneExtension::ChangeHighlightBackground()
       
  1490     {
       
  1491     // Every time the current list item is changed we need to change the
       
  1492     // animation input layer (animated element is the highlight bacground that
       
  1493     // can differ between highlight positions).
       
  1494     if( iAnimation )
       
  1495         {
       
  1496         if( iAnimation->State() == EAknsAnimStateStopped  )
       
  1497             {
       
  1498             // Input layers don't exist when stopped or finished. We need to
       
  1499             // resize to create the input layers and to update the output
       
  1500             // layer.
       
  1501 
       
  1502             TRAPD( err, DoResizeL( iAnimation->Size(), EFalse ) );
       
  1503             NoAnimIfError( err );
       
  1504             }
       
  1505         else // Either paused, running or finished
       
  1506             {
       
  1507             // Update the highlight background
       
  1508             if( iAnimation->InputRgbGc() )
       
  1509                 DrawHighlightBackground( *iAnimation->InputRgbGc() );
       
  1510 
       
  1511             // We need to update the output frame (otherwise the highlight
       
  1512             // would drawn with the old output before the next new animation
       
  1513             // frame).
       
  1514             NoAnimIfError( iAnimation->UpdateOutput() );
       
  1515             }
       
  1516         }
       
  1517     }
       
  1518 
       
  1519 // -----------------------------------------------------------------------------
       
  1520 // CEikMenuPaneExtension::MenuClosed
       
  1521 // -----------------------------------------------------------------------------
       
  1522 //
       
  1523 void CEikMenuPaneExtension::MenuClosed()
       
  1524     {
       
  1525     _AKNTRACE_FUNC_ENTER;
       
  1526     delete iAnimation;
       
  1527     iAnimation = NULL;
       
  1528 
       
  1529     CCoeEnv* env = CCoeEnv::Static();
       
  1530     env->RemoveForegroundObserver( *this );
       
  1531 
       
  1532     iAnimFlags.Set( EFlagUseAnimation );
       
  1533 
       
  1534     delete iSct;
       
  1535     iSct = NULL;
       
  1536     iSctHighlighted = EFalse;
       
  1537 #ifdef RD_UI_TRANSITION_EFFECTS_LIST  
       
  1538     iSctRect = TRect::EUninitialized;
       
  1539 #endif
       
  1540 
       
  1541     if ( iCba )
       
  1542         {
       
  1543         iCba = NULL;
       
  1544         }
       
  1545     
       
  1546     if ( iRedirectionListener )
       
  1547         {
       
  1548         iRedirectionListener->Closing();
       
  1549         }
       
  1550 		
       
  1551     iFlags.Clear( EHideItemSpecificCommands );
       
  1552     iFlags.Clear( EContextSensitive );
       
  1553     iFlags.Clear( EHighlightEnabled );
       
  1554     _AKNTRACE_FUNC_EXIT;
       
  1555     }
       
  1556 
       
  1557 // -----------------------------------------------------------------------------
       
  1558 // CEikMenuPaneExtension::HandleGainingForeground
       
  1559 // The application has gained foreground -> animation should be continued.
       
  1560 // -----------------------------------------------------------------------------
       
  1561 //
       
  1562 void CEikMenuPaneExtension::HandleGainingForeground()
       
  1563     {
       
  1564     // It is safe to start animation in this method because animation is
       
  1565     // deleted when the menu is closed -> it is not possible that menu receives
       
  1566     // foreground event while it is not visible and the animation exists.
       
  1567 
       
  1568     // We need to check if the menu has focus (to prevent running nonfocused
       
  1569     // animation because also the nonfocused menu (menu/submenu) receives
       
  1570     // foreground events)
       
  1571     Play();
       
  1572     }
       
  1573 
       
  1574 // -----------------------------------------------------------------------------
       
  1575 // CEikMenuPaneExtension::HandleLosingForeground
       
  1576 // The application lost foreground -> no running animation (even if the
       
  1577 // application is partially visible).
       
  1578 // -----------------------------------------------------------------------------
       
  1579 //
       
  1580 void CEikMenuPaneExtension::HandleLosingForeground()
       
  1581     {
       
  1582     if( iAnimation )
       
  1583         {
       
  1584         NoAnimIfError( iAnimation->Stop() );
       
  1585         }
       
  1586     }
       
  1587 
       
  1588 // -----------------------------------------------------------------------------
       
  1589 // CEikMenuPaneExtension::AnimFrameReady
       
  1590 // -----------------------------------------------------------------------------
       
  1591 //
       
  1592 void CEikMenuPaneExtension::AnimFrameReady( TInt aError, TInt )
       
  1593     {
       
  1594     if( KErrNone != aError )
       
  1595         {
       
  1596         // Animation has failed to run -> schedule the animation for
       
  1597         // deletion to fall back to normal rendering.
       
  1598         PostDeleteAnimation();
       
  1599         }
       
  1600     else if( iControl ) // Frame ok
       
  1601         {
       
  1602         if ( iControl->IsVisible() )
       
  1603             {
       
  1604             iControl->RepaintHighlight();
       
  1605             }
       
  1606         }
       
  1607     }
       
  1608 
       
  1609 // -----------------------------------------------------------------------------
       
  1610 // CEikMenuPaneExtension::DoCancel
       
  1611 // -----------------------------------------------------------------------------
       
  1612 //
       
  1613 void CEikMenuPaneExtension::DoCancel()
       
  1614     {
       
  1615     // Required method, but not needed
       
  1616     }
       
  1617 
       
  1618 
       
  1619 // -----------------------------------------------------------------------------
       
  1620 // CEikMenuPaneExtension::RunL
       
  1621 // Postponed animation deletion is done here
       
  1622 // -----------------------------------------------------------------------------
       
  1623 //
       
  1624 void CEikMenuPaneExtension::RunL()
       
  1625     {
       
  1626     UseNoAnimation();
       
  1627     }
       
  1628 
       
  1629 // -----------------------------------------------------------------------------
       
  1630 // CEikMenuPaneExtension::Play
       
  1631 // -----------------------------------------------------------------------------
       
  1632 //
       
  1633 void CEikMenuPaneExtension::Play()
       
  1634     {
       
  1635     if( !iAnimation || !iControl->IsFocused() )
       
  1636         {
       
  1637         return;
       
  1638         }
       
  1639 
       
  1640     // No need to start running/finished animation
       
  1641     if( EAknsAnimStateRunning == iAnimation->State() ||
       
  1642         EAknsAnimStateFinished == iAnimation->State() )
       
  1643         {
       
  1644         return;
       
  1645         }
       
  1646 
       
  1647     CAknAppUi* aui = static_cast<CAknAppUi*>(CEikonEnv::Static()->AppUi());
       
  1648     if( !aui->IsForeground() )
       
  1649         {
       
  1650         return;
       
  1651         }
       
  1652 
       
  1653     if( EAknsAnimStatePaused == iAnimation->State() )
       
  1654         {
       
  1655         NoAnimIfError( iAnimation->Continue() );
       
  1656         }
       
  1657     else if( EAknsAnimStateStopped == iAnimation->State() )
       
  1658         {
       
  1659         if( iAnimation->NeedsInputLayer() )
       
  1660             {
       
  1661             TRAPD( err, DoResizeL( iAnimation->Size(), ETrue ) );
       
  1662             NoAnimIfError( err );
       
  1663 
       
  1664             if( KErrNone != err )
       
  1665                 return;
       
  1666             }
       
  1667 
       
  1668         NoAnimIfError( iAnimation->Start() );
       
  1669         }
       
  1670     }
       
  1671 
       
  1672 // -----------------------------------------------------------------------------
       
  1673 // CEikMenuPaneExtension::DrawHighlightBackground
       
  1674 // Draws skinned highlight background to the provided graphics context.
       
  1675 // -----------------------------------------------------------------------------
       
  1676 //
       
  1677 TBool CEikMenuPaneExtension::DrawHighlightBackground( CFbsBitGc& aGc )
       
  1678     {
       
  1679     // Draw the background under the current highlight. This simplified
       
  1680     // drawing, we only grab a piece from the list background bitmap.
       
  1681     MAknsSkinInstance* skin = AknsUtils::SkinInstance();
       
  1682 
       
  1683     return AknsDrawUtils::DrawBackground( skin, iBgContext, iControl, aGc, TPoint(0,0),
       
  1684                                           iControl->HighlightRect(),
       
  1685                                           KAknsDrawParamRGBOnly );
       
  1686     }
       
  1687 
       
  1688 // -----------------------------------------------------------------------------
       
  1689 // CEikMenuPaneExtension::PostDeleteAnimation
       
  1690 // Schedules the animation for deletion by activating the extension itself.
       
  1691 // Deletion is postponed because in many error/failure occasions the caller has
       
  1692 // been animation and direct deletion is possibly not safe (because function
       
  1693 // stack would return through the deleted object).
       
  1694 // -----------------------------------------------------------------------------
       
  1695 //
       
  1696 void CEikMenuPaneExtension::PostDeleteAnimation()
       
  1697     {
       
  1698     TRequestStatus* status = &iStatus;
       
  1699     User::RequestComplete( status, KErrNone );
       
  1700     SetActive();
       
  1701     }
       
  1702 
       
  1703 // -----------------------------------------------------------------------------
       
  1704 // CEikMenuPaneExtension::CreateAnimationL
       
  1705 // -----------------------------------------------------------------------------
       
  1706 //
       
  1707 void CEikMenuPaneExtension::CreateAnimationL( const TSize& aHighlightSize )
       
  1708     {
       
  1709     // Create animation
       
  1710     CCoeEnv* env = CCoeEnv::Static();
       
  1711     env->AddForegroundObserverL( *this );
       
  1712 
       
  1713     delete iAnimation;
       
  1714     iAnimation = NULL;
       
  1715 
       
  1716     iAnimation = CAknsEffectAnim::NewL( this );
       
  1717     TBool ok = iAnimation->ConstructFromSkinL( KAknsIIDQsnAnimList );
       
  1718 
       
  1719     if( !ok ) // Animation for the ID was not found from the skin
       
  1720         {
       
  1721         User::Leave( KErrNotFound );
       
  1722         }
       
  1723 
       
  1724     DoResizeL( aHighlightSize, ETrue );
       
  1725 
       
  1726     Play();
       
  1727     }
       
  1728 
       
  1729 // -----------------------------------------------------------------------------
       
  1730 // CEikMenuPaneExtension::DoResizeL
       
  1731 // -----------------------------------------------------------------------------
       
  1732 //
       
  1733 void CEikMenuPaneExtension::DoResizeL(
       
  1734     const TSize& aHighlightSize, TBool aAboutToStart )
       
  1735     {
       
  1736     iAnimation->BeginConfigInputLayersL( aHighlightSize, aAboutToStart );
       
  1737 
       
  1738     if( iAnimation->InputRgbGc() )
       
  1739         DrawHighlightBackground( *iAnimation->InputRgbGc() );
       
  1740 
       
  1741     iAnimation->EndConfigInputLayersL();
       
  1742     }
       
  1743 
       
  1744 // -----------------------------------------------------------------------------
       
  1745 // CEikMenuPaneExtension::ConstructMenuSctRowL
       
  1746 // Creates a special characters row to be used in edit menu.
       
  1747 // -----------------------------------------------------------------------------
       
  1748 //
       
  1749 void CEikMenuPaneExtension::ConstructMenuSctRowL( TDes& aSpecialChars, TInt aResourceId )
       
  1750     {
       
  1751     _AKNTRACE_FUNC_ENTER;
       
  1752     TBool renew = EFalse;
       
  1753     if (iSct)
       
  1754         {
       
  1755         delete iSct;
       
  1756         iSct = NULL;
       
  1757         renew = ETrue;
       
  1758         }
       
  1759     iSct = new(ELeave) CAknCharMap();
       
  1760     iSct->ConstructMenuSctRowL(aResourceId);
       
  1761     iSct->SetBuffer( aSpecialChars );
       
  1762     if ( renew && iMenuPaneWindow && iControl )
       
  1763         {
       
  1764         iSct->SetContainerWindowL( *iControl );
       
  1765         if ( AknLayoutUtils::PenEnabled() )
       
  1766             {
       
  1767             iSct->SetGloballyCapturing( ETrue );
       
  1768             iSct->SetPointerCapture( ETrue );
       
  1769             }
       
  1770         }
       
  1771     _AKNTRACE_FUNC_EXIT;
       
  1772     }
       
  1773 
       
  1774 // -----------------------------------------------------------------------------
       
  1775 // CEikMenuPaneExtension::ConstructMenuSctRowFromDialogL
       
  1776 // Creates a special characters row to be used in edit menu.
       
  1777 // -----------------------------------------------------------------------------
       
  1778 //
       
  1779 void CEikMenuPaneExtension::ConstructMenuSctRowFromDialogL( TDes& aSpecialChars, TInt aResourceId )
       
  1780     {
       
  1781     TBool renew = EFalse;
       
  1782     if (iSct)
       
  1783         {
       
  1784         delete iSct;
       
  1785         iSct = NULL;
       
  1786         renew = ETrue;
       
  1787         }
       
  1788     iSct = new(ELeave) CAknCharMap();
       
  1789     iSct->ConstructMenuSctRowFromDialogL(aResourceId);
       
  1790     iSct->SetBuffer( aSpecialChars );
       
  1791     if ( renew && iMenuPaneWindow && iControl)
       
  1792         {
       
  1793         iSct->SetContainerWindowL( *iControl );
       
  1794         if ( AknLayoutUtils::PenEnabled() )
       
  1795             {
       
  1796             iSct->SetGloballyCapturing( ETrue );
       
  1797             iSct->SetPointerCapture( ETrue );
       
  1798             }
       
  1799         }
       
  1800     }
       
  1801 
       
  1802 // -----------------------------------------------------------------------------
       
  1803 // CEikMenuPaneExtension::HandleControlEventL
       
  1804 // -----------------------------------------------------------------------------
       
  1805 //
       
  1806 void CEikMenuPaneExtension::HandleControlEventL(CCoeControl* /*aControl*/,TCoeEvent aEventType)
       
  1807     {
       
  1808     _AKNTRACE_FUNC_ENTER;
       
  1809     if ( AknLayoutUtils::PenEnabled() )
       
  1810         {
       
  1811          if(aEventType == EEventStateChanged)
       
  1812             {
       
  1813             // Something has been selected from CharMap
       
  1814             iSpecialCharPointed = ETrue;
       
  1815             }
       
  1816         }
       
  1817     _AKNTRACE( "aEventType = %d", aEventType );
       
  1818     _AKNTRACE_FUNC_EXIT;
       
  1819     }
       
  1820 
       
  1821     
       
  1822 // -----------------------------------------------------------------------------
       
  1823 // CEikMenuPaneExtension::ImmediateFeedback
       
  1824 // -----------------------------------------------------------------------------
       
  1825 //
       
  1826 void CEikMenuPaneExtension::ImmediateFeedback(
       
  1827     TTouchLogicalFeedback aType,
       
  1828     TTouchFeedbackType aFbType  = TTouchFeedbackType( ETouchFeedbackAudio |
       
  1829                                                       ETouchFeedbackVibra ))
       
  1830     {   
       
  1831     if ( iFeedback )
       
  1832         {
       
  1833         iFeedback->InstantFeedback( iControl, aType, aFbType, TPointerEvent() );
       
  1834         }
       
  1835     }
       
  1836 
       
  1837 
       
  1838 // -----------------------------------------------------------------------------
       
  1839 // CEikMenuPaneExtension::PrepareCascadeForItemCommands
       
  1840 // -----------------------------------------------------------------------------
       
  1841 //
       
  1842 void CEikMenuPaneExtension::PrepareCascadeForItemCommands()
       
  1843     {
       
  1844     if ( iFlags.IsSet( ESingleClickEnabled )
       
  1845             && iControl->iOwner
       
  1846             && iControl->iOwner->iExtension )
       
  1847         {
       
  1848         const TBitFlags& ownerFlags( iControl->iOwner->iExtension->iFlags );
       
  1849         if ( ownerFlags.IsSet( EContextSensitive ) )
       
  1850             {
       
  1851             iFlags.Set( EContextSensitive );
       
  1852             }
       
  1853         else if ( ownerFlags.IsSet( EHideItemSpecificCommands ) )
       
  1854             {
       
  1855             iControl->SetItemCommandsDimmed();
       
  1856             }
       
  1857         }
       
  1858     }
       
  1859 
       
  1860 
       
  1861 // -----------------------------------------------------------------------------
       
  1862 // CEikMenuPaneExtension::ContextSensitiveMenu
       
  1863 // -----------------------------------------------------------------------------
       
  1864 //
       
  1865 TBool CEikMenuPaneExtension::ContextSensitiveMenu() const
       
  1866     {
       
  1867     TBool isContextSensitive( EFalse );
       
  1868     if ( !iControl->iOwner )
       
  1869         {
       
  1870         CEikMenuBar* menuBar = static_cast<CEikMenuBar*>( iControl->Parent() );
       
  1871         if ( menuBar && menuBar->GetMenuType() == CEikMenuBar::EMenuContext )
       
  1872             {
       
  1873             isContextSensitive = ETrue;
       
  1874             }
       
  1875         }
       
  1876     return isContextSensitive;
       
  1877     }
       
  1878 
       
  1879 
       
  1880 // -----------------------------------------------------------------------------
       
  1881 // CEikMenuPaneExtension::ItemSpecificCommand
       
  1882 // -----------------------------------------------------------------------------
       
  1883 //
       
  1884 TBool CEikMenuPaneExtension::ItemSpecificCommand( CEikMenuPaneItem& aItem )
       
  1885     {
       
  1886     TBool itemSpecific( EFalse );
       
  1887     if ( ( aItem.iData.iFlags & EEikMenuItemSpecific
       
  1888             || aItem.iData.iFlags & EEikMenuItemSpecificListQuery )
       
  1889             && !( aItem.iData.iFlags & EEikMenuItemDimmed ) )
       
  1890         {
       
  1891         itemSpecific = ETrue;
       
  1892         }
       
  1893     return itemSpecific;
       
  1894     }
       
  1895 
       
  1896 
       
  1897 // -----------------------------------------------------------------------------
       
  1898 // CEikMenuPaneExtension::EnableHighlight
       
  1899 // -----------------------------------------------------------------------------
       
  1900 //
       
  1901 void CEikMenuPaneExtension::EnableHighlight(
       
  1902         TBool aEnabled, TBool aPointerEnabled )
       
  1903     {
       
  1904     TBool wasEnabled( iFlags.IsSet( EHighlightEnabled ) );
       
  1905     if ( aEnabled )
       
  1906         {
       
  1907         iFlags.Set( EHighlightEnabled );
       
  1908         }
       
  1909     else 
       
  1910         {
       
  1911         iFlags.Clear( EHighlightEnabled );
       
  1912         }
       
  1913     if ( !aPointerEnabled
       
  1914             && iCba
       
  1915             && ( ( wasEnabled && !aEnabled ) || ( !wasEnabled && aEnabled ) ) )
       
  1916         {
       
  1917         iCba->MakeCommandVisible( EAknSoftkeySelect, aEnabled );
       
  1918         }
       
  1919     }
       
  1920 
       
  1921 
       
  1922 // -----------------------------------------------------------------------------
       
  1923 // CEikMenuPaneExtension::HighlightEnabled
       
  1924 // -----------------------------------------------------------------------------
       
  1925 //
       
  1926 TBool  CEikMenuPaneExtension::HighlightEnabled()
       
  1927     {
       
  1928     return iFlags.IsSet( EHighlightEnabled );
       
  1929     }
       
  1930 
       
  1931 
       
  1932 // -----------------------------------------------------------------------------
       
  1933 // CEikMenuPaneExtension::SetDefaultHighlight
       
  1934 // -----------------------------------------------------------------------------
       
  1935 //
       
  1936 void CEikMenuPaneExtension::SetDefaultHighlight()
       
  1937     {
       
  1938     TInt item( CEikMenuPane::ENothingSelected );
       
  1939     if ( iSct )
       
  1940         {
       
  1941         iSctHighlighted = ETrue;
       
  1942         }
       
  1943     else
       
  1944         {
       
  1945         item = iControl->iScroller->TopItemIndex();
       
  1946         // Partial item
       
  1947         if ( Offset() != 0 )
       
  1948             {
       
  1949             item++;
       
  1950             }
       
  1951         // Task swapper
       
  1952         TInt taskSwapper;
       
  1953         if ( iControl->MenuItemExists( EAknCmdTaskSwapper, taskSwapper ) )
       
  1954             {
       
  1955             if ( item == taskSwapper )
       
  1956                 {
       
  1957                 item++;
       
  1958                 }
       
  1959             }
       
  1960         }
       
  1961     iControl->SetSelectedItem( item );
       
  1962     EnableHighlight( ETrue );
       
  1963     if ( iControl->IsVisible() )
       
  1964         {
       
  1965         iControl->RepaintHighlight();
       
  1966         }
       
  1967     }
       
  1968 
       
  1969 
       
  1970 // =============================================================================
       
  1971 // Implementation of CEikMenuPane
       
  1972 // =============================================================================
       
  1973 
       
  1974 //
       
  1975 // CItemArray
       
  1976 //
       
  1977 
       
  1978 // -----------------------------------------------------------------------------
       
  1979 // CEikMenuPane::CItemArray::~CItemArray
       
  1980 // -----------------------------------------------------------------------------
       
  1981 //
       
  1982 EXPORT_C CEikMenuPane::CItemArray::~CItemArray()
       
  1983     {
       
  1984     ResetAndDestroy();
       
  1985     }
       
  1986 
       
  1987 // -----------------------------------------------------------------------------
       
  1988 // CEikMenuPane::CItemArray::CItemArray
       
  1989 // -----------------------------------------------------------------------------
       
  1990 //
       
  1991 EXPORT_C CEikMenuPane::CItemArray::CItemArray()
       
  1992     : CArrayPtrFlat<CEikMenuPaneItem>( KItemGranularity )
       
  1993     {
       
  1994     __DECLARE_NAME(_S( "CEikMenuPane::CItemArray") );
       
  1995     }
       
  1996 
       
  1997 // -----------------------------------------------------------------------------
       
  1998 // CEikMenuPane::CItemArray::AddItemL
       
  1999 // Adds the menu pane item aMenuItem to the end of the array owned by the menu pane
       
  2000 // and transfers ownership.
       
  2001 // -----------------------------------------------------------------------------
       
  2002 //
       
  2003 EXPORT_C void CEikMenuPane::CItemArray::AddItemL( CEikMenuPaneItem* aMenuItem )
       
  2004     {
       
  2005     CleanupStack::PushL( aMenuItem );
       
  2006     AppendL( aMenuItem );
       
  2007     CleanupStack::Pop();
       
  2008     }
       
  2009 
       
  2010 //
       
  2011 // CExtendedItemData
       
  2012 //
       
  2013 
       
  2014 CExtendedItemData::~CExtendedItemData()
       
  2015     {
       
  2016     delete iIcon;
       
  2017     delete iScaleableText;
       
  2018     }
       
  2019 
       
  2020 
       
  2021 //
       
  2022 // CEikMenuPaneItem
       
  2023 //
       
  2024 
       
  2025 // -----------------------------------------------------------------------------
       
  2026 // CEikMenuPaneItem::CEikMenuPaneItem
       
  2027 // -----------------------------------------------------------------------------
       
  2028 //
       
  2029 EXPORT_C CEikMenuPaneItem::CEikMenuPaneItem()
       
  2030     {
       
  2031     CreateExtendedDataBlock();
       
  2032     }
       
  2033 
       
  2034 // -----------------------------------------------------------------------------
       
  2035 // CEikMenuPaneItem::~CEikMenuPaneItem
       
  2036 // -----------------------------------------------------------------------------
       
  2037 //
       
  2038 EXPORT_C CEikMenuPaneItem::~CEikMenuPaneItem()
       
  2039     {
       
  2040     delete iExtendedData;
       
  2041     }
       
  2042 
       
  2043 // -----------------------------------------------------------------------------
       
  2044 // CEikMenuPaneItem::SetIcon
       
  2045 // -----------------------------------------------------------------------------
       
  2046 //
       
  2047 EXPORT_C void CEikMenuPaneItem::SetIcon( CGulIcon* aIcon )
       
  2048     {
       
  2049     if ( iExtendedData )
       
  2050         {
       
  2051         if( iExtendedData->iIcon )
       
  2052             {
       
  2053             delete iExtendedData->iIcon;
       
  2054             }
       
  2055 
       
  2056         iExtendedData->iIcon = aIcon;
       
  2057         }
       
  2058     }
       
  2059 
       
  2060 // -----------------------------------------------------------------------------
       
  2061 // CEikMenuPaneItem::DrawItemIcon
       
  2062 // Draws the icon for the item to the graphics context aGc, in the rectangle aRect allocating a square area with
       
  2063 // sides of size of aBitmapSpaceRequired to contain the icon. Draws the icon in a dimmed style if aDimmed is
       
  2064 // ETrue.
       
  2065 // -----------------------------------------------------------------------------
       
  2066 //
       
  2067 EXPORT_C void CEikMenuPaneItem::DrawItemIcon( CWindowGc& aGc,
       
  2068                                               TRect aRect,
       
  2069                                               TBool /*aDimmed*/,
       
  2070                                               TInt /*aBitmapSpaceRequired*/ ) const
       
  2071     {
       
  2072     _AKNTRACE_FUNC_ENTER;
       
  2073     if (iExtendedData && iExtendedData->iIcon)
       
  2074         {
       
  2075         aGc.SetBrushStyle( CGraphicsContext::ENullBrush );
       
  2076         TRect rect( aRect );
       
  2077         AknIconUtils::SetSize(iExtendedData->iIcon->Bitmap(), rect.Size());
       
  2078 
       
  2079         TInt rectWidth = rect.Width();
       
  2080         TInt rectHeight = rect.Height();
       
  2081         TInt iconWidth = iExtendedData->iIcon->Bitmap()->SizeInPixels().iWidth;
       
  2082         TInt iconHeight = iExtendedData->iIcon->Bitmap()->SizeInPixels().iHeight;
       
  2083 
       
  2084         // If aspect ratio of the image and rect do not match the image
       
  2085         // is centered.
       
  2086         if ( rectWidth > iconWidth )
       
  2087             {
       
  2088             rect.iTl.iX += TInt( ( rectWidth - iconWidth ) / 2 );
       
  2089             }
       
  2090         if ( rectHeight > iconHeight )
       
  2091             {
       
  2092             rect.iTl.iY += TInt( ( rectHeight - iconHeight ) / 2 );
       
  2093             }
       
  2094         _AKNTRACE( "rectWidth = %d",  rectWidth );
       
  2095         _AKNTRACE( "rectHeight = %d",  rectHeight );
       
  2096         _AKNTRACE( "iconWidth = %d",  iconWidth );
       
  2097         _AKNTRACE( "iconHeight = %d",  iconHeight );
       
  2098         _AKNTRACE( "rect.iTl.iX = %d",  rect.iTl.iX );
       
  2099         _AKNTRACE( "rect.iTl.iY = %d",  rect.iTl.iY );
       
  2100 
       
  2101         aGc.BitBltMasked( rect.iTl, iExtendedData->iIcon->Bitmap(),
       
  2102                           TRect(0, 0, rect.Width(), rect.Height()),
       
  2103                           iExtendedData->iIcon->Mask(), ETrue);
       
  2104         }
       
  2105     _AKNTRACE_FUNC_EXIT;
       
  2106     }
       
  2107 
       
  2108 // -----------------------------------------------------------------------------
       
  2109 // CEikMenuPaneItem::CreateIconL
       
  2110 // Constructs a new icon for the item, taking ownership of the picture bitmap
       
  2111 // aBitmap and the mask bitmap aMask unless bitmaps have been set to be owned externally.
       
  2112 // -----------------------------------------------------------------------------
       
  2113 //
       
  2114 EXPORT_C void CEikMenuPaneItem::CreateIconL( CFbsBitmap* aBitmap, CFbsBitmap* aMask )
       
  2115     {
       
  2116     if ( iExtendedData )
       
  2117         {
       
  2118         if( iExtendedData->iIcon )
       
  2119             {
       
  2120             delete iExtendedData->iIcon;
       
  2121             }
       
  2122 
       
  2123         iExtendedData->iIcon = CGulIcon::NewL( aBitmap, aMask );
       
  2124         }
       
  2125     }
       
  2126 
       
  2127 /**
       
  2128  *
       
  2129  */
       
  2130 // -----------------------------------------------------------------------------
       
  2131 // CEikMenuPaneItem::IconBitmap
       
  2132 // Returns a pointer to the picture bitmap of the item icon.
       
  2133 // Does not normally imply transfer of ownership.
       
  2134 // -----------------------------------------------------------------------------
       
  2135 //
       
  2136 EXPORT_C CFbsBitmap* CEikMenuPaneItem::IconBitmap() const
       
  2137     {
       
  2138     if ( iExtendedData )
       
  2139         {
       
  2140         return iExtendedData->iIcon ? iExtendedData->iIcon->Bitmap() : NULL;
       
  2141         }
       
  2142 
       
  2143     return NULL;
       
  2144     }
       
  2145 
       
  2146 
       
  2147 // -----------------------------------------------------------------------------
       
  2148 // CEikMenuPaneItem::IconMask
       
  2149 // Returns a pointer to the mask bitmap of the item icon.
       
  2150 // Does not normally imply transfer of ownership.
       
  2151 // -----------------------------------------------------------------------------
       
  2152 //
       
  2153 EXPORT_C CFbsBitmap* CEikMenuPaneItem::IconMask() const
       
  2154     {
       
  2155     if ( iExtendedData )
       
  2156         {
       
  2157         return iExtendedData->iIcon ? iExtendedData->iIcon->Mask() : NULL;
       
  2158         }
       
  2159 
       
  2160     return NULL;
       
  2161     }
       
  2162 
       
  2163 
       
  2164 // -----------------------------------------------------------------------------
       
  2165 // CEikMenuPaneItem::SetBitmapsOwnedExternally
       
  2166 // Sets the item icon to be owned externally if aOwnedExternally is ETrue.
       
  2167 // -----------------------------------------------------------------------------
       
  2168 //
       
  2169 EXPORT_C void CEikMenuPaneItem::SetBitmapsOwnedExternally( TBool aOwnedExternally )
       
  2170     {
       
  2171     if ( iExtendedData )
       
  2172         {
       
  2173         if( iExtendedData->iIcon )
       
  2174             {
       
  2175             iExtendedData->iIcon->SetBitmapsOwnedExternally( aOwnedExternally );
       
  2176             }
       
  2177         }
       
  2178     }
       
  2179 
       
  2180 
       
  2181 // -----------------------------------------------------------------------------
       
  2182 // CEikMenuPaneItem::SetIconBitmapL
       
  2183 // Sets the picture bitmap for the title icon to aBitmap.
       
  2184 // Transfers ownership unless the bitmaps are owned externally.
       
  2185 // -----------------------------------------------------------------------------
       
  2186 //
       
  2187 EXPORT_C void CEikMenuPaneItem::SetIconBitmapL( CFbsBitmap* aBitmap )
       
  2188     {
       
  2189     if ( iExtendedData )
       
  2190         {
       
  2191         if( !iExtendedData->iIcon )
       
  2192             {
       
  2193             iExtendedData->iIcon = CGulIcon::NewL();
       
  2194             }
       
  2195 
       
  2196         iExtendedData->iIcon->SetBitmap( aBitmap );
       
  2197         }
       
  2198     }
       
  2199 
       
  2200 
       
  2201 // -----------------------------------------------------------------------------
       
  2202 // CEikMenuPaneItem::SetIconMaskL
       
  2203 // Sets the mask bitmap for the title icon to aMask.
       
  2204 // Transfers ownership unless the bitmaps are owned externally.
       
  2205 // -----------------------------------------------------------------------------
       
  2206 //
       
  2207 EXPORT_C void CEikMenuPaneItem::SetIconMaskL( CFbsBitmap* aMask )
       
  2208     {
       
  2209     if ( iExtendedData )
       
  2210         {
       
  2211         if( !iExtendedData->iIcon )
       
  2212             {
       
  2213             iExtendedData->iIcon = CGulIcon::NewL();
       
  2214             }
       
  2215 
       
  2216         iExtendedData->iIcon->SetMask( aMask );
       
  2217         }
       
  2218     }
       
  2219 
       
  2220 
       
  2221 // -----------------------------------------------------------------------------
       
  2222 // CEikMenuPaneItem::ScaleableText
       
  2223 // Returns scaleable text. If there isn't scaleable text available
       
  2224 // then this method returns iData.iText.
       
  2225 // -----------------------------------------------------------------------------
       
  2226 //
       
  2227 EXPORT_C TPtrC CEikMenuPaneItem::ScaleableText() const
       
  2228     {
       
  2229     if ( ( iExtendedData ) && ( iExtendedData->iScaleableText ) )
       
  2230         {
       
  2231         return iExtendedData->iScaleableText->Des();
       
  2232         }
       
  2233 
       
  2234     return iData.iText;
       
  2235     }
       
  2236 
       
  2237 
       
  2238 // -----------------------------------------------------------------------------
       
  2239 // CEikMenuPaneItem::SetScaleableTextL
       
  2240 // Sets scaleable text. iData.iText is set to first text version.
       
  2241 // -----------------------------------------------------------------------------
       
  2242 //
       
  2243 EXPORT_C void CEikMenuPaneItem::SetScaleableTextL( const TDesC& aText )
       
  2244     {
       
  2245     if ( iExtendedData )
       
  2246         {
       
  2247         if ( iExtendedData->iScaleableText )
       
  2248             {
       
  2249             delete iExtendedData->iScaleableText;
       
  2250             iExtendedData->iScaleableText = NULL;
       
  2251             }
       
  2252 
       
  2253         iData.iText = GetNominalText( aText );
       
  2254 
       
  2255         if ( IsScaleableText( aText ) )
       
  2256             {
       
  2257             iExtendedData->iScaleableText = HBufC::NewL( aText.Length() );
       
  2258             iExtendedData->iScaleableText->Des().Copy( aText );
       
  2259             }
       
  2260         }
       
  2261     }
       
  2262 
       
  2263 
       
  2264 // -----------------------------------------------------------------------------
       
  2265 // CEikMenuPaneItem::GetNominalText
       
  2266 // -----------------------------------------------------------------------------
       
  2267 //
       
  2268 TPtrC CEikMenuPaneItem::GetNominalText( const TDesC& aText )
       
  2269     {
       
  2270     TInt limit = aText.Length();
       
  2271     TInt border = aText.Locate( TChar( KScaleableTextSeparator ) );
       
  2272     if ( border != KErrNotFound )
       
  2273         {
       
  2274         limit = border;
       
  2275         }
       
  2276 
       
  2277     limit = ( limit > CEikMenuPaneItem::SData::ENominalTextLength ? CEikMenuPaneItem::SData::ENominalTextLength : limit );
       
  2278 
       
  2279     return aText.Left( limit);
       
  2280     }
       
  2281 
       
  2282 
       
  2283 
       
  2284 //
       
  2285 // class CEikMenuPane
       
  2286 //
       
  2287 
       
  2288 // -----------------------------------------------------------------------------
       
  2289 // CEikMenuPane::~CEikMenuPane
       
  2290 // -----------------------------------------------------------------------------
       
  2291 //
       
  2292 EXPORT_C CEikMenuPane::~CEikMenuPane()
       
  2293     {
       
  2294     _AKNTRACE_FUNC_ENTER;
       
  2295     AKNTASHOOK_REMOVE();
       
  2296     CloseCascadeMenu();
       
  2297     if ( !ItemArrayOwnedExternally() )
       
  2298         {
       
  2299         delete iItemArray;
       
  2300         iItemArray  = NULL;
       
  2301         }
       
  2302     else
       
  2303         {
       
  2304         ResetItemArray();
       
  2305         }
       
  2306 
       
  2307     if ( iLaunchingButton )
       
  2308         {
       
  2309         TPointerEvent event;
       
  2310         event.iType = TPointerEvent::EButton1Up;
       
  2311         event.iModifiers = 0;
       
  2312         event.iPosition = iLaunchingButton->Position();
       
  2313         TRAP_IGNORE( iLaunchingButton->HandlePointerEventL( event ) );
       
  2314         iLaunchingButton = NULL; // not owned
       
  2315         }
       
  2316 
       
  2317     delete iScroller;
       
  2318     iScroller = NULL;
       
  2319 
       
  2320     delete iSBFrame;
       
  2321     iSBFrame = NULL;
       
  2322 
       
  2323     iMenuObserver = NULL; // not owned
       
  2324 
       
  2325     iEditMenuObserver = NULL; // not owned
       
  2326 
       
  2327     iOwner = NULL; // not owned
       
  2328 
       
  2329     delete iExtension;
       
  2330     iExtension = NULL;
       
  2331     _AKNTRACE_FUNC_EXIT;
       
  2332     }
       
  2333 
       
  2334 // -----------------------------------------------------------------------------
       
  2335 // CEikMenuPane::CEikMenuPane
       
  2336 // -----------------------------------------------------------------------------
       
  2337 //
       
  2338 EXPORT_C CEikMenuPane::CEikMenuPane( MEikMenuObserver* aMenuObserver )
       
  2339     : iMenuObserver( aMenuObserver )
       
  2340     {
       
  2341     _AKNTRACE_FUNC_ENTER;
       
  2342     __ASSERT_DEBUG( iMenuObserver,Panic( EEikPanicNullPointer ) );
       
  2343     __DECLARE_NAME(_S("CEikMenuPane"));
       
  2344     iBorder = TGulBorder( AknBorderId::EAknBorderMenuSubmenuPopup ); // AKNLAF
       
  2345     iAllowPointerUpEvents = EFalse;
       
  2346     iNumberOfDragEvents = 0;
       
  2347     MakeVisible( EFalse );
       
  2348     AKNTASHOOK_ADD( this, "CEikMenuPane" );
       
  2349     _AKNTRACE_FUNC_EXIT;
       
  2350     }
       
  2351 
       
  2352 // -----------------------------------------------------------------------------
       
  2353 // CEikMenuPane::ConstructL
       
  2354 // -----------------------------------------------------------------------------
       
  2355 //
       
  2356 EXPORT_C void CEikMenuPane::ConstructL( CEikMenuPane* aOwner, MEikMenuObserver* aEditMenuObserver )
       
  2357     {
       
  2358     _AKNTRACE_FUNC_ENTER;
       
  2359     iOwner = aOwner;
       
  2360     iEditMenuObserver = aEditMenuObserver;
       
  2361 
       
  2362     CheckCreateScrollerL();
       
  2363     CheckCreateExtensionL();
       
  2364 
       
  2365     iExtension->iTransitionsOn = FeatureManager::FeatureSupported( KFeatureIdUiTransitionEffects );
       
  2366 
       
  2367     CreateWindowL( iCoeEnv->RootWin() );
       
  2368     EnableWindowTransparency();
       
  2369     SetAllowStrayPointers();
       
  2370     EnableDragEvents();
       
  2371 
       
  2372     TAknWindowLineLayout menuLineLayout;
       
  2373     if ( iOwner ) // submenu
       
  2374         {
       
  2375         menuLineLayout = AknLayoutScalable_Avkon::list_single_popup_submenu_pane( 0 ).LayoutLine();
       
  2376         }
       
  2377     else
       
  2378         {
       
  2379         menuLineLayout = AknLayoutScalable_Avkon::list_single_pane_cp2( 0 ).LayoutLine();
       
  2380         }
       
  2381 
       
  2382     TRect windowRect = Rect();
       
  2383     TAknLayoutRect menuLayoutRect;
       
  2384     menuLayoutRect.LayoutRect( windowRect, menuLineLayout );
       
  2385     iItemHeight = menuLayoutRect.Rect().Height();
       
  2386 
       
  2387     if ( iExtension->iSct )
       
  2388         {
       
  2389         RWindow* window = (RWindow*)this->DrawableWindow();
       
  2390         iExtension->iMenuPaneWindow = window;
       
  2391         iExtension->iSct->SetContainerWindowL( *this );
       
  2392 
       
  2393         if ( AknLayoutUtils::PenEnabled() )
       
  2394             {
       
  2395             // This is effectively the same as CCoeControl::EnableDragEvents()
       
  2396             // which is protected.
       
  2397             window->PointerFilter( EPointerFilterDrag, 0 );
       
  2398             iExtension->iSct->SetGloballyCapturing( ETrue );
       
  2399             iExtension->iSct->SetPointerCapture( ETrue );
       
  2400             iExtension->iSct->SetObserver(iExtension);
       
  2401             }
       
  2402         }
       
  2403 
       
  2404     if ( iOwner ) // submenu
       
  2405         {
       
  2406         SetPointerCapture( ETrue );
       
  2407         }
       
  2408 
       
  2409     LoadCascadeBitmapL();
       
  2410     LoadCheckMarkBitmapL();
       
  2411     LoadRadioButtonBitmapL();
       
  2412 
       
  2413     // Window may not be created if OOM earlier during construction
       
  2414     RWindow* window = &Window();
       
  2415     if( window == NULL )
       
  2416         User::Leave( KErrNoMemory );
       
  2417             
       
  2418     Window().SetOrdinalPosition( 0 );
       
  2419     
       
  2420     Window().SetPointerGrab( ETrue );
       
  2421     SetGloballyCapturing( ETrue );
       
  2422 
       
  2423     iExtension->iPhysics->UpdateViewWindowControl(); 
       
  2424     _AKNTRACE_FUNC_EXIT;
       
  2425     }
       
  2426 
       
  2427 
       
  2428 // -----------------------------------------------------------------------------
       
  2429 // CEikMenuPane::ConstructFromResourceL
       
  2430 // Constructs the menu pane using the resource reader aReader, filling the menu item array with the
       
  2431 // list of menu items provided by the resource file.
       
  2432 // -----------------------------------------------------------------------------
       
  2433 //
       
  2434 EXPORT_C void CEikMenuPane::ConstructFromResourceL( TResourceReader& aReader )
       
  2435     {
       
  2436     if ( iItemArray && !ItemArrayOwnedExternally() )
       
  2437         {
       
  2438         delete iItemArray;
       
  2439         iItemArray = NULL;
       
  2440         }
       
  2441     CreateItemArrayL();
       
  2442 
       
  2443     TAknWindowLineLayout menuLineLayout;
       
  2444     if ( iOwner ) // submenu
       
  2445         {
       
  2446         menuLineLayout = AKN_LAYOUT_WINDOW_list_single_popup_submenu_pane( 0, 0 );
       
  2447         }
       
  2448     else
       
  2449         {
       
  2450         menuLineLayout = AKN_LAYOUT_WINDOW_list_single_popup_menu_pane( 0 );
       
  2451         }
       
  2452     TRect windowRect = Rect();
       
  2453     TAknLayoutRect menuLayoutRect;
       
  2454     menuLayoutRect.LayoutRect( windowRect, menuLineLayout );
       
  2455     iItemHeight = menuLayoutRect.Rect().Height();
       
  2456 
       
  2457     CheckCreateScrollerL();
       
  2458     CheckCreateExtensionL();
       
  2459 
       
  2460     const TInt count=aReader.ReadInt16();
       
  2461     for ( TInt ii=0; ii<count; ++ii )
       
  2462         {
       
  2463         CEikMenuPaneItem* item = new(ELeave) CEikMenuPaneItem();
       
  2464         CleanupStack::PushL( item );
       
  2465         item->iData.iCommandId = aReader.ReadInt32();
       
  2466         item->iData.iCascadeId = aReader.ReadInt32();
       
  2467         item->iData.iFlags = aReader.ReadInt32();
       
  2468         TPtrC txtptr = aReader.ReadTPtrC();
       
  2469         item->SetScaleableTextL( txtptr );
       
  2470         TPtrC extratxtptr = aReader.ReadTPtrC();
       
  2471         item->iData.iExtraText = extratxtptr;
       
  2472         CreateIconFromResourceL( aReader, *item );
       
  2473         CleanupStack::Pop(); // pop first, since additem pushes again
       
  2474         iItemArray->AddItemL( item );
       
  2475         aReader.ReadInt32(); // extension link
       
  2476 
       
  2477         if ( item->iData.iFlags&( EEikMenuItemRadioStart|EEikMenuItemRadioMiddle|EEikMenuItemRadioEnd ) )
       
  2478             {
       
  2479             iExtension->iHasRadioGroup = ETrue;
       
  2480             if ( item->iData.iFlags&EEikMenuItemSymbolOn )
       
  2481                 {
       
  2482                 iExtension->iSelectedRadioButtonItem = ii;
       
  2483                 }
       
  2484             }
       
  2485         }
       
  2486 
       
  2487     aReader.ReadInt32(); // extension link
       
  2488     }
       
  2489 
       
  2490 // -----------------------------------------------------------------------------
       
  2491 // CEikMenuPane::AddMenuItemsL
       
  2492 // -----------------------------------------------------------------------------
       
  2493 //
       
  2494 EXPORT_C void CEikMenuPane::AddMenuItemsL( TInt aResourceId, TInt aPreviousId, TBool /*aAddSeperator*/ )
       
  2495     {
       
  2496     if ( !iItemArray )
       
  2497         {
       
  2498         CreateItemArrayL();
       
  2499         }
       
  2500     
       
  2501     // Read from resource and add items after the item with 'aPreviousId'
       
  2502     TResourceReader reader;
       
  2503     iEikonEnv->CreateResourceReaderLC( reader, aResourceId );
       
  2504 
       
  2505     TInt position = iItemArray->Count();
       
  2506     if ( aPreviousId )
       
  2507         {
       
  2508         ItemAndPos( aPreviousId, position );
       
  2509         position++;
       
  2510         }
       
  2511 
       
  2512     // 'Active Applications' menu item is forced to be first
       
  2513     // item in the options menu.
       
  2514     if (aResourceId == R_AVKON_MENUPANE_TASK_SWAPPER)
       
  2515         {
       
  2516         position = 0;
       
  2517         }
       
  2518 
       
  2519     const TInt count = reader.ReadInt16();
       
  2520     for (TInt ii = 0; ii < count; ++ii)
       
  2521         {
       
  2522         CEikMenuPaneItem* item = new(ELeave) CEikMenuPaneItem();
       
  2523         CleanupStack::PushL( item );
       
  2524         item->iData.iCommandId = reader.ReadInt32();
       
  2525         item->iData.iCascadeId = reader.ReadInt32();
       
  2526         item->iData.iFlags = reader.ReadInt32();
       
  2527         TPtrC txtptr = reader.ReadTPtrC();
       
  2528         item->SetScaleableTextL( txtptr );
       
  2529         TPtrC extratxtptr = reader.ReadTPtrC();
       
  2530         item->iData.iExtraText = extratxtptr;
       
  2531         CreateIconFromResourceL( reader, *item );
       
  2532         iItemArray->InsertL( position++, item );
       
  2533         reader.ReadInt32(); // extension link
       
  2534         CleanupStack::Pop();
       
  2535 
       
  2536         if ( item->iData.iFlags&(EEikMenuItemRadioStart|EEikMenuItemRadioMiddle|EEikMenuItemRadioEnd) )
       
  2537             {
       
  2538             iExtension->iHasRadioGroup = ETrue;
       
  2539             if ( item->iData.iFlags&EEikMenuItemSymbolOn )
       
  2540                 {
       
  2541                 iExtension->iSelectedRadioButtonItem = ii; // so if there are several on, we have only the last of them to be activated
       
  2542                 }
       
  2543             }
       
  2544         }
       
  2545     CleanupStack::PopAndDestroy();// reader
       
  2546     }
       
  2547 
       
  2548 // -----------------------------------------------------------------------------
       
  2549 // CEikMenuPane::FilterDimmedItems
       
  2550 // -----------------------------------------------------------------------------
       
  2551 //
       
  2552 void CEikMenuPane::FilterDimmedItems()
       
  2553     {
       
  2554     TInt pos = iItemArray->Count() - 1;
       
  2555     while ( pos >= 0 )
       
  2556         {
       
  2557         CEikMenuPaneItem* item = (*iItemArray)[pos];
       
  2558         if ( item->iData.iFlags&EEikMenuItemDimmed )
       
  2559             {
       
  2560             DeleteMenuItem( item->iData.iCommandId );
       
  2561             }
       
  2562         pos--;
       
  2563         }
       
  2564     }
       
  2565 
       
  2566 
       
  2567 // -----------------------------------------------------------------------------
       
  2568 // CEikMenuPane::SetScrollBarOnLeft
       
  2569 // Sets the scroll bar to occupy the left side of the menu pane if aOnLeft is ETrue
       
  2570 //
       
  2571 // @since ER5U
       
  2572 // -----------------------------------------------------------------------------
       
  2573 //
       
  2574 EXPORT_C void CEikMenuPane::SetScrollBarOnLeft(TBool aOnLeft)
       
  2575     {
       
  2576     if ( aOnLeft )
       
  2577         {
       
  2578         iFlags |= EEikMenuItemScrollBarLeft;
       
  2579         }
       
  2580     else
       
  2581         {
       
  2582         iFlags &= (~EEikMenuItemScrollBarLeft);
       
  2583         }
       
  2584     }
       
  2585 
       
  2586 
       
  2587 // -----------------------------------------------------------------------------
       
  2588 // CEikMenuPane::SetArrowHeadScrollBar
       
  2589 // Sets the menu pane to use an arrow head scroll bar if aArrowHead is ETrue.
       
  2590 //
       
  2591 // @since ER5U
       
  2592 // -----------------------------------------------------------------------------
       
  2593 //
       
  2594 EXPORT_C void CEikMenuPane::SetArrowHeadScrollBar( TBool /*aArrowHead*/ )
       
  2595     {
       
  2596     }
       
  2597 
       
  2598 
       
  2599 // -----------------------------------------------------------------------------
       
  2600 // CEikMenuPane::ResetItemArray
       
  2601 // Resets the menu's array of items and destroys its elements.
       
  2602 //
       
  2603 // @since ER5U
       
  2604 // -----------------------------------------------------------------------------
       
  2605 //
       
  2606 void CEikMenuPane::ResetItemArray()
       
  2607     {
       
  2608     if ( !iItemArray )
       
  2609         {
       
  2610         return;
       
  2611         }
       
  2612     iItemArray->ResetAndDestroy();
       
  2613     }
       
  2614 
       
  2615 // -----------------------------------------------------------------------------
       
  2616 // CEikMenuPane::CreateItemArrayL
       
  2617 // Creates a new item array to be owned by the menu pane.
       
  2618 //
       
  2619 // @since ER5U
       
  2620 // -----------------------------------------------------------------------------
       
  2621 //
       
  2622 void CEikMenuPane::CreateItemArrayL()
       
  2623     {
       
  2624     iItemArray = new(ELeave) CItemArray;
       
  2625     }
       
  2626 
       
  2627 // -----------------------------------------------------------------------------
       
  2628 // CEikMenuPane::CreateIconFromResourceL
       
  2629 // Creates an icon for the menu item aItem using the resource reader aReader.
       
  2630 //
       
  2631 // @since ER5U
       
  2632 // -----------------------------------------------------------------------------
       
  2633 //
       
  2634 void CEikMenuPane::CreateIconFromResourceL( TResourceReader& aReader, CEikMenuPaneItem& aItem ) const
       
  2635     {
       
  2636     TPtrC bitmapFile = aReader.ReadTPtrC();
       
  2637     TInt bitmapId = aReader.ReadInt16();
       
  2638     TInt bitmapMaskId = aReader.ReadInt16();
       
  2639     if ( bitmapId != -1 )
       
  2640         {
       
  2641         CFbsBitmap* bitmap = NULL;
       
  2642         CFbsBitmap* bitmapMask = NULL;
       
  2643 
       
  2644         if ( bitmapId == EMbmAvkonQgn_indi_app_open_add )
       
  2645             {
       
  2646             MAknsSkinInstance* skin = AknsUtils::SkinInstance();
       
  2647             AknsUtils::CreateIconLC(skin,
       
  2648             KAknsIIDQgnIndiAppOpen,
       
  2649             bitmap, bitmapMask,
       
  2650                 bitmapFile,
       
  2651                 bitmapId, bitmapMaskId);
       
  2652             }
       
  2653         else
       
  2654             {
       
  2655             AknIconUtils::CreateIconLC(bitmap, bitmapMask,
       
  2656                 bitmapFile,
       
  2657                 bitmapId, bitmapMaskId);
       
  2658             }
       
  2659 
       
  2660         aItem.CreateIconL(bitmap, bitmapMask);
       
  2661         CleanupStack::Pop(2); // bitmap, bitmapMask.
       
  2662         }
       
  2663     }
       
  2664 
       
  2665 
       
  2666 // -----------------------------------------------------------------------------
       
  2667 // CEikMenuPane::Reset
       
  2668 // Destroys the menu pane's item array and scroll bar frame.
       
  2669 // -----------------------------------------------------------------------------
       
  2670 //
       
  2671 EXPORT_C void CEikMenuPane::Reset()
       
  2672     {
       
  2673     delete iItemArray;
       
  2674     iItemArray = NULL;
       
  2675     delete iSBFrame;
       
  2676     iSBFrame = NULL;
       
  2677     }
       
  2678 
       
  2679 
       
  2680 // -----------------------------------------------------------------------------
       
  2681 // CEikMenuPane::CloseCascadeMenu
       
  2682 // Closes and destroys any current cascade menu and takes focus back.
       
  2683 // Does nothing if no cascade menu exists.
       
  2684 // -----------------------------------------------------------------------------
       
  2685 //
       
  2686 EXPORT_C void CEikMenuPane::CloseCascadeMenu()
       
  2687     {
       
  2688     CloseCascadeMenu( EFalse );
       
  2689     }
       
  2690 
       
  2691 // -----------------------------------------------------------------------------
       
  2692 // CEikMenuPane::TryLaunchCascadeMenuL
       
  2693 // -----------------------------------------------------------------------------
       
  2694 //
       
  2695 void CEikMenuPane::TryLaunchCascadeMenuL(const CEikMenuPaneItem& aItem)
       
  2696     {
       
  2697     _AKNTRACE_FUNC_ENTER;
       
  2698     iExtension->iShowCascadeTransition = EFalse;
       
  2699     iExtension->iButtonDownItem = KErrNotFound;
       
  2700     if ( aItem.iData.iFlags&EEikMenuItemDimmed )
       
  2701         {
       
  2702         iMenuObserver->HandleAttemptDimmedSelectionL( aItem.iData.iCommandId );
       
  2703         return;
       
  2704         }
       
  2705     LaunchCascadeMenuL( aItem.iData.iCascadeId );
       
  2706     _AKNTRACE_FUNC_EXIT;
       
  2707     }
       
  2708 
       
  2709 // -----------------------------------------------------------------------------
       
  2710 // CEikMenuPane::LaunchCascadeMenuL
       
  2711 // -----------------------------------------------------------------------------
       
  2712 //
       
  2713 void CEikMenuPane::LaunchCascadeMenuL( TInt aCascadeMenuId )
       
  2714     {
       
  2715     _AKNTRACE_FUNC_ENTER;
       
  2716 #ifdef THIS_IS_CORRECT_CODE_BUT_DISABLED_BECAUSE_OF_TEST_APPS
       
  2717     // Series 60 does not have cascade options menus from another cascade menus..
       
  2718     if ( iOwner ) return;
       
  2719 #endif // THIS_IS_CORRECT_CODE_BUT_DISABLED_BECAUSE_OF_TEST_APPS
       
  2720 
       
  2721     TInt err( KErrNone );
       
  2722     TRAP( err, iCascadeMenuPane = new(ELeave) CEikMenuPane( iMenuObserver ));
       
  2723     iCascadeMenuPane->SetMopParent( this );
       
  2724     iCascadeMenuPane->SetObserver( Observer() );
       
  2725     
       
  2726     // delete object here so that new cascade menu pane does not get the same
       
  2727     // address -> messes up transition registration..
       
  2728     if( iExtension->iCascadeMenuObject )
       
  2729         {
       
  2730         GfxTransEffect::Deregister( iExtension->iCascadeMenuObject );
       
  2731         }
       
  2732               
       
  2733     delete iExtension->iCascadeMenuObject;
       
  2734     iExtension->iCascadeMenuObject = NULL;
       
  2735     
       
  2736     User::LeaveIfError( err );
       
  2737     
       
  2738     // register cascade options menu
       
  2739     GfxTransEffect::Register( iCascadeMenuPane, KGfxOptionsMenuCascadeControlUid, EFalse );
       
  2740     TRAP( err, DoLaunchCascadeMenuL( aCascadeMenuId ) );
       
  2741     if ( err )
       
  2742         {
       
  2743         CloseCascadeMenu();
       
  2744         User::Leave( err );
       
  2745         }
       
  2746     _AKNTRACE_FUNC_EXIT;
       
  2747     }
       
  2748 
       
  2749 // -----------------------------------------------------------------------------
       
  2750 // CEikMenuPane::DoLaunchCascadeMenuL
       
  2751 // -----------------------------------------------------------------------------
       
  2752 //
       
  2753 void CEikMenuPane::DoLaunchCascadeMenuL( TInt aCascadeMenuId )
       
  2754     {
       
  2755     _AKNTRACE_FUNC_ENTER;
       
  2756     if ( !iItemArray || iItemArray->Count() == 0 )
       
  2757         {
       
  2758         return;
       
  2759         }
       
  2760     iCascadeMenuPane->ConstructL( this, iEditMenuObserver );
       
  2761     iCascadeMenuPane->SetSelectedItem( 0 );
       
  2762 
       
  2763     // Stop menu pane physics when launching cascade menu 
       
  2764     iExtension->iPhysics->StopPhysics();
       
  2765     iExtension->iPhysics->ResetFriction();
       
  2766 
       
  2767     iMenuObserver->RestoreMenuL(iCascadeMenuPane,aCascadeMenuId,MEikMenuObserver::EMenuPane);
       
  2768     MEikMenuObserver* fepMenuObserver =  CAknEnv::Static()->FepMenuObserver();
       
  2769     if (fepMenuObserver)
       
  2770         {
       
  2771         fepMenuObserver->DynInitMenuPaneL( aCascadeMenuId, iCascadeMenuPane );
       
  2772         }
       
  2773     if (iEditMenuObserver)
       
  2774         {
       
  2775         iEditMenuObserver->DynInitMenuPaneL( aCascadeMenuId, iCascadeMenuPane );
       
  2776         }
       
  2777 
       
  2778     iCascadeMenuPane->iExtension->PrepareCascadeForItemCommands();
       
  2779     iCascadeMenuPane->iExtension->EnableHighlight( EFalse );
       
  2780     iCascadeMenuPane->FilterDimmedItems();
       
  2781 
       
  2782     // cascade menu launch animation
       
  2783     if ( iExtension->iRedirectionListener )
       
  2784         {
       
  2785         iExtension->iRedirectionListener->LaunchCascadeMenu();
       
  2786         }
       
  2787     else
       
  2788         {
       
  2789         iExtension->StartCascadeMenuAppearTransition();
       
  2790         }
       
  2791 
       
  2792     if( AknLayoutUtils::PenEnabled() )
       
  2793         {
       
  2794         TTouchLogicalFeedback fbLogicalType = ETouchFeedbackPopUp;
       
  2795         if ( CAknTransitionUtils::TransitionsEnabled( AknTransEffect::EComponentTransitionsOff ) )
       
  2796             {
       
  2797             fbLogicalType = ETouchFeedbackIncreasingPopUp;
       
  2798             }
       
  2799         iExtension->ImmediateFeedback( fbLogicalType,
       
  2800                                        ETouchFeedbackVibra );
       
  2801         }
       
  2802     _AKNTRACE_FUNC_EXIT;
       
  2803     }
       
  2804 
       
  2805 // -----------------------------------------------------------------------------
       
  2806 // CEikMenuPane::CalculateSizeAndPosition
       
  2807 // Calculates and returns the menu pane's size.
       
  2808 // Also sets the rectangle of the menu pane.
       
  2809 // -----------------------------------------------------------------------------
       
  2810 //
       
  2811 TRect CEikMenuPane::CalculateSizeAndPosition()
       
  2812     {
       
  2813     _AKNTRACE_FUNC_ENTER;
       
  2814     TRect retVal;
       
  2815 
       
  2816     TInt numItemsInPane = 0;
       
  2817     if ( iItemArray )
       
  2818         {// Min size is for 1 item even if menu is empty
       
  2819         numItemsInPane = iItemArray->Count();
       
  2820         }
       
  2821 
       
  2822     if ( iExtension->iSct )
       
  2823         {
       
  2824         numItemsInPane++;
       
  2825         }
       
  2826 
       
  2827     TInt maxNumItemsInMenu = AknLayoutScalable_Avkon::
       
  2828                     list_single_pane_cp2_ParamLimits().LastRow() + 1;
       
  2829     TInt maxNumItemsInSubMenu = AknLayoutScalable_Avkon::
       
  2830                     list_single_popup_submenu_pane_ParamLimits().LastRow() + 1;
       
  2831 
       
  2832     TInt maxItemsInView = NumberOfItemsThatFitInView();
       
  2833 
       
  2834     if (iExtension && iExtension->iSct)
       
  2835         {
       
  2836         maxItemsInView++;
       
  2837         }
       
  2838 
       
  2839     numItemsInPane = Min( Max( 1, numItemsInPane ), maxItemsInView);
       
  2840 
       
  2841     TRect windowRect;
       
  2842     AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EPopupParent, windowRect );
       
  2843 
       
  2844     retVal = CalculateSizeAndPositionScalable( windowRect, numItemsInPane );
       
  2845     _AKNTRACE_FUNC_EXIT;
       
  2846     return retVal;
       
  2847     }
       
  2848 
       
  2849 // -----------------------------------------------------------------------------
       
  2850 // CEikMenuPane::StartDisplayingMenuPane
       
  2851 // -----------------------------------------------------------------------------
       
  2852 //
       
  2853 EXPORT_C void CEikMenuPane::StartDisplayingMenuPane( const CEikHotKeyTable* /*aHotKeyTable*/,
       
  2854                                                      const TPoint& /*aTargetPos*/,
       
  2855                                                      const CEikMenuPaneTitle* /*aMenuPaneTitle*/,
       
  2856                                                      TInt /*aMinTitleWidth*/,
       
  2857                                                      TPopupTargetPosType /*aTargetType*/ )
       
  2858     {
       
  2859     _AKNTRACE_FUNC_ENTER;
       
  2860     if ( iExtension->iRedirectionListener )
       
  2861         {
       
  2862         iExtension->iRedirectionListener->AppearTransitionStarting();
       
  2863         }
       
  2864 
       
  2865     CreateScrollBarFrame();
       
  2866 
       
  2867     iExtension->iPressedDown = EFalse;
       
  2868     iExtension->SetOffset( 0 );
       
  2869     iExtension->iHasIcon = MenuHasIcon();
       
  2870 
       
  2871     if ( iExtension->iTransitionsOn )
       
  2872         {
       
  2873         CAknTransitionUtils::SetAllParents( this );
       
  2874         }
       
  2875 
       
  2876     const TSize screenSize( iEikonEnv->EikAppUi()->ApplicationRect().Size() );
       
  2877 
       
  2878     CEikCba *cba = 0;
       
  2879     MopGetObject(cba);
       
  2880     if ( cba )
       
  2881         {
       
  2882         cba->SetSkinBackgroundId( KAknsIIDQsnBgAreaControlPopup );
       
  2883         }
       
  2884 
       
  2885     iScroller->SetTopItemIndex(0); // to avoid broken values of topitemindex
       
  2886     
       
  2887     // set highlight visible if menu was opened via HW keys
       
  2888     if ( iCoeEnv->LastEvent().Type() == EEventKey
       
  2889             && iCoeEnv->LastEvent().Key()
       
  2890             && iCoeEnv->LastEvent().Key()->iCode == EKeyCBA1 )
       
  2891         {        
       
  2892         SetDefaultHighlight();
       
  2893         }    
       
  2894 
       
  2895     TRect rect( CalculateSizeAndPosition() );
       
  2896     TPoint newPos( rect.iTl );
       
  2897     TSize menuSize( rect.Size() );
       
  2898 
       
  2899     SetExtent( newPos, menuSize );
       
  2900 
       
  2901     // We need to set the background context when calling create for the
       
  2902     // first time. Otherwise iExtension->iBgContext would have tiny
       
  2903     // rectangles and grabbing the highlight background would produce
       
  2904     // white.
       
  2905     UpdateBackgroundContext( Rect() );
       
  2906 
       
  2907     // The extent has been set. This is the first safe point in code to
       
  2908     // construct animations (because before this highlight related layout code
       
  2909     // will produce invalid results
       
  2910     if( iExtension )
       
  2911         {
       
  2912         // Creates animation only if it does not exist
       
  2913         iExtension->CreateAnimation();        
       
  2914         }
       
  2915         
       
  2916     // Initialize physics engine
       
  2917     TRAP_IGNORE ( iExtension->InitPhysicsL() );
       
  2918         
       
  2919     MakeVisible(ETrue);
       
  2920     SetFocus(ETrue);
       
  2921     Window().SetPointerGrab( ETrue );    
       
  2922 
       
  2923     if ( iExtension->iSct )
       
  2924         {
       
  2925         iExtension->iSctHighlighted = ETrue;
       
  2926         iSelectedItem = ENothingSelected;
       
  2927         // If SCT row existing, set the default focus on SCT row not the top
       
  2928         }
       
  2929 
       
  2930     if (iSelectedItem != ENothingSelected)
       
  2931         {
       
  2932         ScrollToMakeItemVisible(iSelectedItem);
       
  2933         }
       
  2934     PrepareHighlightFrame();
       
  2935     SetCascadedIconSize();
       
  2936         TRAP_IGNORE( ActivateL());
       
  2937     if (iMenuPaneTitle)
       
  2938         {
       
  2939         CONST_CAST(CEikMenuPaneTitle*,iMenuPaneTitle)->MakeVisible(ETrue);
       
  2940         TRAP_IGNORE( CONST_CAST(CEikMenuPaneTitle*,iMenuPaneTitle)->ActivateL());
       
  2941         iMenuPaneTitle->DrawNow();
       
  2942         }
       
  2943 
       
  2944     TRAP_IGNORE( DoUpdateScrollBarL() );
       
  2945 
       
  2946     // No highlight - hide softkey
       
  2947     if ( iExtension && iExtension->iCba )
       
  2948         {
       
  2949         iExtension->iCba->MakeCommandVisible( EAknSoftkeySelect,
       
  2950                 iExtension->iFlags.IsSet(
       
  2951                         CEikMenuPaneExtension::EHighlightEnabled ) );
       
  2952         }
       
  2953 
       
  2954     _AKNTRACE_FUNC_EXIT;
       
  2955     }
       
  2956 
       
  2957 
       
  2958 // -----------------------------------------------------------------------------
       
  2959 // CEikMenuPane::UpdateBackgroundContext
       
  2960 // -----------------------------------------------------------------------------
       
  2961 //
       
  2962 void CEikMenuPane::UpdateBackgroundContext( const TRect& aWindowRect )
       
  2963     {
       
  2964     _AKNTRACE_FUNC_ENTER;
       
  2965     TAknLayoutRect topLeft;
       
  2966     TAknLayoutRect bottomRight;
       
  2967     TAknsItemID frameIID;
       
  2968     TAknsItemID frameCenterIID;
       
  2969     
       
  2970     TRect backgroundRect( iExtension->GetBackgroundRect( aWindowRect ) );     
       
  2971         
       
  2972     if( iOwner ) //for sub menu
       
  2973         {
       
  2974         topLeft.LayoutRect( aWindowRect, SkinLayout::Submenu_skin_placing_Line_2() );
       
  2975         bottomRight.LayoutRect( aWindowRect, SkinLayout::Submenu_skin_placing_Line_5() );
       
  2976         frameIID = KAknsIIDQsnFrPopupSub;
       
  2977         frameCenterIID = KAknsIIDQsnFrPopupCenterSubmenu;
       
  2978         }
       
  2979     else
       
  2980         {
       
  2981         topLeft.LayoutRect( backgroundRect, SkinLayout::Popup_windows_skin_placing__frame_general__Line_2() );
       
  2982         bottomRight.LayoutRect( backgroundRect, SkinLayout::Popup_windows_skin_placing__frame_general__Line_5() );
       
  2983         frameIID = KAknsIIDQsnFrPopup;
       
  2984         frameCenterIID = KAknsIIDQsnFrPopupCenterMenu;
       
  2985         }
       
  2986 
       
  2987     TRect outerRect( topLeft.Rect().iTl, bottomRight.Rect().iBr );
       
  2988     TRect innerRect( topLeft.Rect().iBr, bottomRight.Rect().iTl );
       
  2989 
       
  2990     if( iExtension )
       
  2991         {
       
  2992         iExtension->iBgContext->SetFrame( frameIID );
       
  2993         iExtension->iBgContext->SetCenter( frameCenterIID );
       
  2994         iExtension->iBgContext->SetFrameRects( outerRect, innerRect );
       
  2995         }
       
  2996     _AKNTRACE( " outerRect.iTl.iX = %d",   outerRect.iTl.iX );
       
  2997     _AKNTRACE( " outerRect.iTl.iY = %d",   outerRect.iTl.iY );
       
  2998     _AKNTRACE( " outerRect.iBr.iX = %d",   outerRect.iBr.iX );
       
  2999     _AKNTRACE( " outerRect.iBr.iY = %d",   outerRect.iBr.iY );
       
  3000     
       
  3001     _AKNTRACE( " innerRect.iTl.iX = %d",   innerRect.iTl.iX );
       
  3002     _AKNTRACE( " innerRect.iTl.iY = %d",   innerRect.iTl.iY );
       
  3003     _AKNTRACE( " innerRect.iBr.iX = %d",   innerRect.iBr.iX );
       
  3004     _AKNTRACE( " innerRect.iBr.iY = %d",   innerRect.iBr.iY );
       
  3005     _AKNTRACE_FUNC_EXIT;
       
  3006     }
       
  3007 
       
  3008 // -----------------------------------------------------------------------------
       
  3009 // CEikMenuPane::RepaintHighlight
       
  3010 // -----------------------------------------------------------------------------
       
  3011 //
       
  3012 void CEikMenuPane::RepaintHighlight() const
       
  3013     {
       
  3014     if ( !iExtension->iSctHighlighted )
       
  3015         {
       
  3016         DrawItem( SelectedItem(), EDrawHighlight );
       
  3017         }
       
  3018     }
       
  3019 
       
  3020 
       
  3021 // -----------------------------------------------------------------------------
       
  3022 // CEikMenuPane::MoveHighlightTo
       
  3023 // Moves the menu pane highlight to the new selected menu item aNewSelectedItem.
       
  3024 // -----------------------------------------------------------------------------
       
  3025 //
       
  3026 EXPORT_C void CEikMenuPane::MoveHighlightTo(TInt aNewSelectedItem)
       
  3027     {
       
  3028     _AKNTRACE_FUNC_ENTER;
       
  3029     _AKNTRACE( "aNewSelectedItem =  %d", aNewSelectedItem );
       
  3030     _AKNTRACE( "iSelectedItem =  %d", iSelectedItem );
       
  3031     if ( aNewSelectedItem == iSelectedItem )
       
  3032         {
       
  3033         return;
       
  3034         }
       
  3035     
       
  3036     iExtension->StopCascadeMenuTimer();
       
  3037     TInt previousTopItem = iScroller->TopItemIndex();
       
  3038     TInt previousSelectedItem = iSelectedItem;
       
  3039     _AKNTRACE( "previousTopItem =  %d", previousTopItem );
       
  3040     _AKNTRACE( "previousSelectedItem =  %d", previousSelectedItem );
       
  3041 
       
  3042     ActivateGc();
       
  3043 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  3044     MAknListBoxTfxInternal *transApi = CAknListLoader::TfxApiInternal( iExtension->iGc );
       
  3045     if ( transApi )
       
  3046         {
       
  3047         iExtension->iGc->Activate( *DrawableWindow() );
       
  3048         }
       
  3049     CWindowGc& gc = transApi ? *iExtension->iGc : SystemGc();
       
  3050 #else
       
  3051     CWindowGc& gc =  SystemGc();
       
  3052 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  3053     PrepareGcForDrawingItems( gc );
       
  3054 
       
  3055     // Scrollers top item index must be updated first because setting selected
       
  3056     // item results in animation redraw (which requires knowledge about the
       
  3057     // current top item).
       
  3058     if ( aNewSelectedItem >= 0 )
       
  3059         {
       
  3060         ScrollToMakeItemVisible( aNewSelectedItem );
       
  3061         }
       
  3062     else
       
  3063         {
       
  3064         ScrollToMakeItemVisible( 0 );
       
  3065         }
       
  3066 
       
  3067     TInt topItem = iScroller->TopItemIndex();
       
  3068     TInt bottomItem = topItem + NumberOfItemsThatFitInView();
       
  3069     if( bottomItem > NumberOfItemsInPane() )
       
  3070         {
       
  3071         bottomItem = NumberOfItemsInPane();
       
  3072         }
       
  3073     _AKNTRACE( "topItem =  %d", topItem );
       
  3074     _AKNTRACE( "bottomItem =  %d", bottomItem );
       
  3075     // When the SCT row will be highlight, remove highlight from
       
  3076     // bottom's and top's item.
       
  3077     if (iExtension->iSctHighlighted)
       
  3078         {
       
  3079         DrawItem( gc, topItem, ERemoveHighlight );
       
  3080         DrawItem( gc, (bottomItem-1), ERemoveHighlight );
       
  3081         }
       
  3082     SetSelectedItem( aNewSelectedItem );
       
  3083 
       
  3084     PrepareHighlightFrame();
       
  3085 
       
  3086     if ( previousTopItem == topItem  && aNewSelectedItem >= 0 )
       
  3087         {
       
  3088         // then only previuosly and currently selected items should be redrawn
       
  3089         DrawItem( gc, previousSelectedItem, ERemoveHighlight );
       
  3090 
       
  3091         if ( !iExtension->iSctHighlighted )
       
  3092             {
       
  3093             DrawItem( gc, aNewSelectedItem, EDrawHighlight );
       
  3094             }
       
  3095         }
       
  3096     else
       
  3097         {
       
  3098         TBool skipHighlight = EFalse;
       
  3099         if (iExtension && iExtension->iSct && aNewSelectedItem == 0 &&
       
  3100             previousSelectedItem > 1)
       
  3101             {
       
  3102             skipHighlight = ETrue;
       
  3103             }
       
  3104         for( TInt i = topItem; i<bottomItem; i++ )
       
  3105             {
       
  3106             if( i == aNewSelectedItem && !skipHighlight)
       
  3107                 {
       
  3108                 DrawItem( gc, i, EDrawHighlight );
       
  3109                 }
       
  3110             else
       
  3111                 {
       
  3112                 DrawItem( gc, i, ERemoveHighlight );
       
  3113                 }
       
  3114             }
       
  3115         }
       
  3116 
       
  3117 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  3118     if ( transApi )
       
  3119         {
       
  3120         iExtension->iGc->Deactivate();
       
  3121         }
       
  3122 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  3123     DeactivateGc();
       
  3124 
       
  3125     UpdateScrollBarThumbs();
       
  3126     
       
  3127     // Updating view position here prevents some flickering
       
  3128     iExtension->ViewPositionChanged( iExtension->iViewPosition );   
       
  3129 
       
  3130     _AKNTRACE_FUNC_EXIT;
       
  3131     }
       
  3132 
       
  3133 // -----------------------------------------------------------------------------
       
  3134 // CEikMenuPane::PrepareGcForDrawingItems
       
  3135 // -----------------------------------------------------------------------------
       
  3136 //
       
  3137 void CEikMenuPane::PrepareGcForDrawingItems(CGraphicsContext& aGc) const
       
  3138     {
       
  3139 
       
  3140     // BIDI
       
  3141     /*
       
  3142      * get the fonts from the LAF!
       
  3143      * Do we need to get them here? - nope - moved to DrawItem()
       
  3144      */    
       
  3145 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  3146     MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( iExtension->iGc );
       
  3147     if ( transApi )
       
  3148         {
       
  3149         transApi->StartDrawing( MAknListBoxTfxInternal::EListNotSpecified );
       
  3150         }
       
  3151 #endif
       
  3152 
       
  3153     aGc.SetPenColor(iEikonEnv->ControlColor( EColorMenuPaneText, *this) );
       
  3154 #if defined(MENU_TEXTURED_BACKGROUND)
       
  3155     iEikonEnv->SetTexturedBrush( aGc );
       
  3156 #else
       
  3157     aGc.SetBrushStyle( CGraphicsContext::ESolidBrush );
       
  3158     aGc.SetBrushColor( iEikonEnv->ControlColor( EColorMenuPaneBackground,*this ) );
       
  3159 #endif
       
  3160 
       
  3161 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  3162     if ( transApi )
       
  3163         {
       
  3164         transApi->StopDrawing();
       
  3165         }
       
  3166 #endif
       
  3167     }
       
  3168 
       
  3169 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  3170 /**
       
  3171  * Iterate through the visible items in a menu and calculate minimum 
       
  3172  * item margins that dont need drawing.
       
  3173  */
       
  3174 void CEikMenuPaneExtension::CalcItemSize( MAknListBoxTfxInternal* transApi ) const
       
  3175     {
       
  3176     if ( transApi && iControl->iItemArray && iControl->iItemArray->Count() )
       
  3177         {
       
  3178         TRect marginRect(TRect::EUninitialized);
       
  3179         const TInt index = 0;
       
  3180 
       
  3181         // Specifies whether the text should be moved to give some space for icon.
       
  3182         TInt hasIcon = iControl->MenuHasIcon() ? 1 : 0;
       
  3183 
       
  3184         TAknWindowLineLayout menuPane( AKN_LAYOUT_WINDOW_list_menu_pane( 0 , 0 ) );
       
  3185         TAknWindowLineLayout singleMenuPane(
       
  3186                         AKN_LAYOUT_WINDOW_list_single_popup_menu_pane( index ) );
       
  3187         TAknTextLineLayout menuTextLayout(
       
  3188                         AKN_LAYOUT_TEXT_List_pane_texts__menu_single__Line_1(0) );
       
  3189         
       
  3190         TAknLayoutRect menuPaneRect;
       
  3191         TAknLayoutRect singleMenuPaneRect;
       
  3192         TAknLayoutText textRect;
       
  3193         
       
  3194         TBool hasCascade = EFalse;
       
  3195         TBool hasNonCascade = EFalse;
       
  3196         
       
  3197         // number of items in the whole menu
       
  3198         for(TInt i = 0; i < iControl->iItemArray->Count(); i++)
       
  3199             {
       
  3200             CEikMenuPaneItem* item = (*iControl->iItemArray)[i];
       
  3201             
       
  3202             // true if a cascade symbol must be drawn (main menu only)
       
  3203             TBool cascade = item->iData.iCascadeId != 0;
       
  3204             
       
  3205             if ( cascade )
       
  3206                 {
       
  3207                 if ( hasCascade )
       
  3208                     {
       
  3209                     if ( hasNonCascade )
       
  3210                         {
       
  3211                         break;
       
  3212                         }
       
  3213                     continue;
       
  3214                     }
       
  3215                 hasCascade = ETrue;
       
  3216                 }
       
  3217             else
       
  3218                 {
       
  3219                 if ( hasNonCascade )
       
  3220                     {
       
  3221                     if ( hasCascade )
       
  3222                         {
       
  3223                         break;
       
  3224                         }
       
  3225                     continue;
       
  3226                     }
       
  3227                 hasNonCascade = ETrue;
       
  3228                 }
       
  3229     
       
  3230             if ( !iControl->iOwner )
       
  3231                 {
       
  3232                 TAknWindowLineLayout listScrollPaneLayout( 
       
  3233                     AknLayoutScalable_Avkon::listscroll_menu_pane(0).LayoutLine() );
       
  3234                 AdjustPopupLayoutData( listScrollPaneLayout );                 
       
  3235                 TAknLayoutRect listScrollPaneRect;
       
  3236                 listScrollPaneRect.LayoutRect( iControl->Rect(), listScrollPaneLayout );
       
  3237     
       
  3238                 menuPane = AknLayoutScalable_Avkon::list_menu_pane( 0 ).LayoutLine();
       
  3239                 menuPaneRect.LayoutRect( listScrollPaneRect.Rect(), menuPane );
       
  3240     
       
  3241                 singleMenuPane = AknLayoutScalable_Avkon::list_single_pane_cp2( index ).LayoutLine();
       
  3242                 singleMenuPaneRect.LayoutRect( menuPaneRect.Rect(), singleMenuPane );
       
  3243     
       
  3244                 menuTextLayout = AknLayoutScalable_Avkon::list_single_pane_t1_cp2( cascade ? 3 : 0 ).LayoutLine();
       
  3245                 }
       
  3246             else // Submenu
       
  3247                 {
       
  3248                 TBool hasDoubleSpanScrollBar = EFalse;
       
  3249                 if ( iControl->iOwner && iControl->iSBFrame && 
       
  3250                         iControl->iSBFrame->VScrollBarVisibility() )
       
  3251                     {
       
  3252                     hasDoubleSpanScrollBar = ETrue;
       
  3253                     }
       
  3254                 TAknWindowLineLayout listScrollPaneLayout( AknLayoutScalable_Avkon::listscroll_popup_sub_pane().LayoutLine() );
       
  3255                 TAknLayoutRect listScrollPaneRect;
       
  3256                 listScrollPaneRect.LayoutRect( iControl->Rect(), listScrollPaneLayout );
       
  3257     
       
  3258                 menuPane = AknLayoutScalable_Avkon::list_submenu_pane( !hasDoubleSpanScrollBar ).LayoutLine();
       
  3259                 menuPaneRect.LayoutRect( listScrollPaneRect.Rect(), menuPane );
       
  3260     
       
  3261                 singleMenuPane = AknLayoutScalable_Avkon::list_single_popup_submenu_pane( index ).LayoutLine();
       
  3262                 singleMenuPaneRect.LayoutRect( menuPaneRect.Rect(), singleMenuPane );
       
  3263     
       
  3264                 menuTextLayout = TAknTextLineLayout( AknLayoutScalable_Avkon::list_single_popup_submenu_pane_t1( hasIcon ).LayoutLine() );
       
  3265                 }
       
  3266             
       
  3267             textRect.LayoutText( singleMenuPaneRect.Rect(), menuTextLayout );
       
  3268             if (marginRect == TRect::EUninitialized) 
       
  3269                 {
       
  3270                 marginRect = textRect.TextRect();
       
  3271                 }
       
  3272             else
       
  3273                 {
       
  3274                 marginRect.BoundingRect(textRect.TextRect());
       
  3275                 }
       
  3276             
       
  3277             if ( cascade )
       
  3278                 {
       
  3279                 TAknWindowLineLayout elementCascade( AknLayoutScalable_Avkon::list_single_pane_cp2_g3().LayoutLine());
       
  3280                 TAknLayoutRect cascadeRect;
       
  3281                 cascadeRect.LayoutRect( singleMenuPaneRect.Rect(), elementCascade );
       
  3282                 marginRect.BoundingRect(cascadeRect.Rect());
       
  3283                 }
       
  3284             else
       
  3285                 {
       
  3286                 TAknLayoutRect activeApplicationsIconRect;
       
  3287                 activeApplicationsIconRect.LayoutRect( singleMenuPaneRect.Rect(),
       
  3288                     AknLayoutScalable_Avkon::list_single_pane_g1_cp2(0).LayoutLine() );
       
  3289                 marginRect.BoundingRect(activeApplicationsIconRect.Rect());
       
  3290                 }
       
  3291             }
       
  3292 
       
  3293         if ( hasIcon )
       
  3294             {
       
  3295             TAknLayoutRect iconLayoutRect;
       
  3296             iconLayoutRect.LayoutRect( singleMenuPaneRect.Rect(),
       
  3297                 AknLayoutScalable_Avkon::list_single_popup_submenu_pane_g1().LayoutLine() );
       
  3298             marginRect.BoundingRect(iconLayoutRect.Rect());
       
  3299             }
       
  3300 
       
  3301         //send margins to tfx
       
  3302         TPoint tl ( marginRect.iTl - menuPaneRect.Rect().iTl );
       
  3303         transApi->SetPosition( MAknListBoxTfxInternal::EListTLMargin, tl );
       
  3304         
       
  3305         TPoint br( singleMenuPaneRect.Rect().Size().AsPoint() - marginRect.iBr + menuPaneRect.Rect().iTl );
       
  3306         transApi->SetPosition( MAknListBoxTfxInternal::EListBRMargin, br );
       
  3307         }
       
  3308     }
       
  3309 #endif
       
  3310 
       
  3311 
       
  3312 // ---------------------------------------------------------------------------
       
  3313 // CEikMenuPane::DrawItem
       
  3314 // ---------------------------------------------------------------------------
       
  3315 //
       
  3316 void CEikMenuPane::DrawItem( TInt aItem, THighlightType aHighlight ) const
       
  3317     {
       
  3318     ActivateGc();
       
  3319 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  3320     MAknListBoxTfxInternal* transApi = 
       
  3321         CAknListLoader::TfxApiInternal( iExtension->iGc );
       
  3322 
       
  3323     if ( transApi )
       
  3324         {
       
  3325         iExtension->iGc->Activate( *DrawableWindow() );
       
  3326         }
       
  3327     
       
  3328     CWindowGc& gc = transApi ? *iExtension->iGc : SystemGc();
       
  3329 #else
       
  3330     CWindowGc& gc = SystemGc();
       
  3331 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  3332     PrepareGcForDrawingItems( gc );
       
  3333     DrawItem( gc, aItem, aHighlight );
       
  3334     
       
  3335 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  3336     if ( transApi )
       
  3337         {
       
  3338         iExtension->iGc->Deactivate();
       
  3339         }
       
  3340 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  3341     DeactivateGc();
       
  3342     }
       
  3343 
       
  3344 
       
  3345 // ---------------------------------------------------------------------------
       
  3346 // CEikMenuPane::DrawItem
       
  3347 // ---------------------------------------------------------------------------
       
  3348 //
       
  3349 void CEikMenuPane::DrawItem(CWindowGc& aGc,TInt aItem,THighlightType aHighlight) const
       
  3350 // BIDI - no hotkey text.  No pre-adornments
       
  3351     {
       
  3352     if ( !iItemArray || iItemArray->Count() == 0 || aItem == ENothingSelected )
       
  3353         {
       
  3354         return;
       
  3355         }
       
  3356 
       
  3357     TInt numItemsInArray = iItemArray->Count();
       
  3358     
       
  3359     __ASSERT_DEBUG( aItem < numItemsInArray, Panic( EEikPanicNoSuchMenuItem ) );
       
  3360     
       
  3361     if ( aItem >= numItemsInArray )
       
  3362         {
       
  3363         return;
       
  3364         }
       
  3365     
       
  3366     // seem to have window owning control in correct place
       
  3367     TRect windowRect = Rect();
       
  3368 
       
  3369     if ( !iOwner )
       
  3370         {
       
  3371         windowRect.iBr.iY -= ( iExtension->iCba->Rect().Height() );    
       
  3372         }
       
  3373     
       
  3374     CEikMenuPaneItem* item = (*iItemArray)[aItem];
       
  3375     // Max visible number of items in menu / submenu
       
  3376     TInt maxNumberOfItems = NumberOfItemsThatFitInView();
       
  3377     
       
  3378     TInt topIndex = iScroller->TopItemIndex();
       
  3379     // true if a cascade symbol must be drawn (main menu only)
       
  3380     TBool cascade = ( item->iData.iCascadeId != 0 );
       
  3381 
       
  3382     // Specifies whether the text should be moved to give some space for icon.
       
  3383     TBool hasIcon = MenuHasIcon();
       
  3384     
       
  3385     if ( iExtension->iSct )
       
  3386         {
       
  3387         ++maxNumberOfItems;
       
  3388         ++numItemsInArray;
       
  3389         }
       
  3390 
       
  3391     // number of items in the whole menu
       
  3392     TInt numItems = Min( Max( 1, numItemsInArray ), maxNumberOfItems );
       
  3393     TInt index =  aItem - topIndex;
       
  3394 
       
  3395     if ( iExtension->iSct )
       
  3396         {
       
  3397         // Sct row exists -> the rest of the menu items are pushed down
       
  3398         // in visual representation.
       
  3399         ++index;
       
  3400         }
       
  3401     TInt itemLeftInBottom = maxNumberOfItems -(numItemsInArray - topIndex);
       
  3402     if ( (itemLeftInBottom > 0) && (topIndex > 0) ) 
       
  3403         {
       
  3404         index += itemLeftInBottom;
       
  3405         }
       
  3406 
       
  3407     TBool drawPartialItem(EFalse);
       
  3408     if ( index == maxNumberOfItems )
       
  3409         {
       
  3410         // We have partial items to draw because of panning so there
       
  3411         // is one more item to draw than normally.
       
  3412         drawPartialItem = ETrue;
       
  3413         // There is no layout data for the extra item, so we used the one
       
  3414         // above it. 
       
  3415         --index;
       
  3416         }
       
  3417 
       
  3418     // If in Menu Sct, skip the first row of the recent used characters
       
  3419     if ( index < 0 || index >= maxNumberOfItems || (iExtension->iSct && index==0))
       
  3420         {
       
  3421         return;  // only interested in drawing visible items
       
  3422         }
       
  3423 
       
  3424     // Collect all of the information from the Layout DLL. Initialise these
       
  3425     // variables with DUMMY data. Then replace it with menu/submenu data.
       
  3426     TAknWindowLineLayout menuPane( AKN_LAYOUT_WINDOW_list_menu_pane( 0 , 0 ) );
       
  3427     TAknWindowLineLayout singleMenuPane(
       
  3428                     AKN_LAYOUT_WINDOW_list_single_popup_menu_pane( index ) );
       
  3429     TAknTextLineLayout menuTextLayout(
       
  3430                     AKN_LAYOUT_TEXT_List_pane_texts__menu_single__Line_1(0) );
       
  3431     TAknLayoutRect menuPaneRect;
       
  3432     TAknLayoutRect singleMenuPaneRect;
       
  3433 
       
  3434     if ( !iOwner )
       
  3435         {
       
  3436         TAknWindowLineLayout listScrollPaneLayout( 
       
  3437             AknLayoutScalable_Avkon::listscroll_menu_pane(0).LayoutLine() );
       
  3438         if ( iExtension )
       
  3439             {
       
  3440             iExtension->AdjustPopupLayoutData( listScrollPaneLayout );
       
  3441             }        
       
  3442         TAknLayoutRect listScrollPaneRect;
       
  3443         listScrollPaneRect.LayoutRect( windowRect, listScrollPaneLayout );
       
  3444 
       
  3445         menuPane = AknLayoutScalable_Avkon::list_menu_pane( 0 ).LayoutLine();
       
  3446         menuPaneRect.LayoutRect( listScrollPaneRect.Rect(), menuPane );
       
  3447 
       
  3448         singleMenuPane = AknLayoutScalable_Avkon::list_single_pane_cp2( index ).LayoutLine();
       
  3449         singleMenuPaneRect.LayoutRect( menuPaneRect.Rect(), singleMenuPane );
       
  3450 
       
  3451         menuTextLayout = AknLayoutScalable_Avkon::list_single_pane_t1_cp2( cascade ? 3 : 0 ).LayoutLine();
       
  3452         }
       
  3453     else // Submenu
       
  3454         {
       
  3455         TBool hasDoubleSpanScrollBar = EFalse;
       
  3456         if ( iSBFrame && iSBFrame->VScrollBarVisibility() )
       
  3457             {
       
  3458             hasDoubleSpanScrollBar = ETrue;
       
  3459             }
       
  3460 
       
  3461         TAknWindowLineLayout listScrollPaneLayout( AknLayoutScalable_Avkon::listscroll_popup_sub_pane().LayoutLine() );
       
  3462         TAknLayoutRect listScrollPaneRect;
       
  3463         listScrollPaneRect.LayoutRect( windowRect, listScrollPaneLayout );
       
  3464 
       
  3465         menuPane = AknLayoutScalable_Avkon::list_submenu_pane( !hasDoubleSpanScrollBar ).LayoutLine();
       
  3466         menuPaneRect.LayoutRect( listScrollPaneRect.Rect(), menuPane );
       
  3467 
       
  3468         singleMenuPane = AknLayoutScalable_Avkon::list_single_popup_submenu_pane( index ).LayoutLine();
       
  3469         singleMenuPaneRect.LayoutRect( menuPaneRect.Rect(), singleMenuPane );
       
  3470 
       
  3471         menuTextLayout = TAknTextLineLayout( AknLayoutScalable_Avkon::list_single_popup_submenu_pane_t1( 0 ).LayoutLine() );
       
  3472 
       
  3473         if ( hasIcon )
       
  3474             {
       
  3475             menuTextLayout = TAknTextLineLayout( AknLayoutScalable_Avkon::list_single_popup_submenu_pane_t1( 1 ).LayoutLine() );
       
  3476             }
       
  3477         }
       
  3478 
       
  3479     TRect itemRect( singleMenuPaneRect.Rect() );
       
  3480      
       
  3481     // Move the rect with our panning offset.
       
  3482     itemRect.iTl.iY += iExtension->Offset();
       
  3483     itemRect.iBr.iY += iExtension->Offset();
       
  3484     if( drawPartialItem )
       
  3485         {        
       
  3486         // For the extra item, also move it one full item height
       
  3487         itemRect.iTl.iY += iItemHeight;
       
  3488         itemRect.iBr.iY += iItemHeight;
       
  3489         }
       
  3490     
       
  3491     TBool drawingInitiated = ETrue;
       
  3492 
       
  3493     RWindow& window = Window();
       
  3494     
       
  3495     if ( &window && window.GetDrawRect() == TRect::EUninitialized )
       
  3496         {
       
  3497 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  3498         MAknListBoxTfxInternal* transApi =
       
  3499             CAknListLoader::TfxApiInternal( &aGc );
       
  3500         drawingInitiated = transApi && !transApi->EffectsDisabled();
       
  3501 #else
       
  3502         drawingInitiated = EFalse;
       
  3503 #endif
       
  3504         }
       
  3505 
       
  3506     if ( !drawingInitiated )
       
  3507         {
       
  3508         window.Invalidate( itemRect );
       
  3509         window.BeginRedraw( itemRect );
       
  3510         }
       
  3511 
       
  3512     MAknsSkinInstance* skin = AknsUtils::SkinInstance();
       
  3513     MAknsControlContext* cc = NULL;
       
  3514     if( iExtension )
       
  3515         {
       
  3516         cc = iExtension->iBgContext;
       
  3517         }
       
  3518     TBool background( ETrue );
       
  3519 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  3520     MAknListBoxTfxInternal *transApi = CAknListLoader::TfxApiInternal( &aGc );
       
  3521     if ( transApi && !transApi->EffectsDisabled() )
       
  3522         {
       
  3523         iExtension->iGc->Activate( *DrawableWindow() );
       
  3524         }
       
  3525 #endif
       
  3526 
       
  3527 #ifdef RD_UI_TRANSITION_EFFECTS_LIST            
       
  3528     if ( !transApi || transApi->EffectsDisabled() )
       
  3529         {
       
  3530 #endif                
       
  3531         aGc.SetBrushStyle( CGraphicsContext::ESolidBrush );
       
  3532         aGc.SetBrushColor( singleMenuPaneRect.Color() );
       
  3533 
       
  3534         if(!iExtension->iFullRedraw)
       
  3535             {
       
  3536             background = AknsDrawUtils::Background(
       
  3537                 skin, cc, this, aGc, itemRect,
       
  3538                 KAknsDrawParamNoClearUnderImage );
       
  3539             }
       
  3540 
       
  3541         if( !background )
       
  3542             {
       
  3543             aGc.SetBrushStyle( CGraphicsContext::ESolidBrush );
       
  3544             aGc.SetPenStyle( CGraphicsContext::ENullPen );
       
  3545             aGc.SetPenColor( singleMenuPaneRect.Color() );
       
  3546             aGc.SetBrushColor( singleMenuPaneRect.Color() );         
       
  3547             aGc.DrawRect( itemRect );
       
  3548             }
       
  3549 #ifdef RD_UI_TRANSITION_EFFECTS_LIST            
       
  3550         }
       
  3551 #endif
       
  3552 
       
  3553     if ( !iExtension->HighlightEnabled() )
       
  3554         {
       
  3555         aHighlight = ENoHighlight;
       
  3556         }
       
  3557 
       
  3558     switch ( aHighlight )
       
  3559         {
       
  3560         case EDrawHighlight :
       
  3561             {
       
  3562             if ( !iExtension->iSctHighlighted )
       
  3563                 {
       
  3564 #ifdef RD_UI_TRANSITION_EFFECTS_LIST                
       
  3565                 if ( transApi )
       
  3566                     {
       
  3567                     // This will remove the old bitmap
       
  3568                     transApi->Invalidate( MAknListBoxTfxInternal::EListHighlight ); 
       
  3569                                        
       
  3570                     transApi->BeginRedraw( MAknListBoxTfxInternal::EListHighlight,
       
  3571                                            itemRect );                                           
       
  3572                     transApi->StartDrawing( MAknListBoxTfxInternal::EListHighlight );
       
  3573                     }
       
  3574 #endif
       
  3575 
       
  3576                 // Partial items, so prevent drawing over the edge of menu pane
       
  3577 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  3578                 if ( !transApi || ( transApi && transApi->EffectsDisabled() ) )
       
  3579                     {
       
  3580                     aGc.SetClippingRect(menuPaneRect.Rect());
       
  3581                     }
       
  3582 #else
       
  3583                 aGc.SetClippingRect(menuPaneRect.Rect());
       
  3584 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  3585 
       
  3586                 TBool drawOk = EFalse;
       
  3587                 if( iExtension->iAnimation ) // Draw animated highlight
       
  3588                     {
       
  3589 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  3590                     if ( transApi && transApi->VerifyKml() == KErrNone )
       
  3591                         {
       
  3592                         Extension()->UseNoAnimation();
       
  3593                         }
       
  3594                     else
       
  3595                         {
       
  3596 #endif
       
  3597                     TAknLayoutRect highlightTopLeft;
       
  3598                     TAknLayoutRect highlightBottomRight;
       
  3599           
       
  3600                     highlightTopLeft.LayoutRect( itemRect,
       
  3601                         SkinLayout::List_highlight_skin_placing__popup_windows__Line_2() );
       
  3602                     highlightBottomRight.LayoutRect( itemRect,
       
  3603                         SkinLayout::List_highlight_skin_placing__popup_windows__Line_5() );
       
  3604                        
       
  3605                     TRect outerRect( highlightTopLeft.Rect().iTl, highlightBottomRight.Rect().iBr );
       
  3606 
       
  3607                     drawOk = iExtension->iAnimation->Render( aGc, outerRect );
       
  3608 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  3609                         }
       
  3610 #endif
       
  3611                     }
       
  3612                 
       
  3613                 if( !drawOk )
       
  3614                     {
       
  3615                     // Animated highlight was not available, use normal skinned
       
  3616                     // rendering.
       
  3617 
       
  3618                     // Because of transparency, background must be drawn here as well
       
  3619                     // (as frame may be see-through)
       
  3620                     aGc.SetBrushStyle( CGraphicsContext::ESolidBrush );
       
  3621                     aGc.SetBrushColor( singleMenuPaneRect.Color() );
       
  3622 
       
  3623                     AknsDrawUtils::Background(
       
  3624                         skin, cc, this, aGc, itemRect,
       
  3625                         KAknsDrawParamNoClearUnderImage );
       
  3626 
       
  3627                     TAknLayoutRect highlightTopLeft;
       
  3628                     TAknLayoutRect highlightBottomRight;
       
  3629 
       
  3630                     highlightTopLeft.LayoutRect(itemRect,
       
  3631                         SkinLayout::List_highlight_skin_placing__popup_windows__Line_2() );
       
  3632                     highlightBottomRight.LayoutRect(itemRect,
       
  3633                         SkinLayout::List_highlight_skin_placing__popup_windows__Line_5() );
       
  3634                     TRect outerRect( highlightTopLeft.Rect().iTl, highlightBottomRight.Rect().iBr );
       
  3635                     TRect innerRect( highlightTopLeft.Rect().iBr, highlightBottomRight.Rect().iTl );
       
  3636 
       
  3637                     drawOk = AknsDrawUtils::DrawFrame( skin, 
       
  3638                                                        aGc, 
       
  3639                                                        outerRect, 
       
  3640                                                        innerRect, 
       
  3641                                                        KAknsIIDQsnFrList, 
       
  3642                                                        KAknsIIDDefault );
       
  3643                     
       
  3644                     }
       
  3645 
       
  3646                 // Both animated highlight and normal highlight drawing have
       
  3647                 // failed.
       
  3648                 if( !drawOk )
       
  3649                     {
       
  3650                     TAknLayoutRect shadowRect;
       
  3651                     TAknLayoutRect highlightRect;
       
  3652                     shadowRect.LayoutRect( itemRect,
       
  3653                         AKN_LAYOUT_WINDOW_Highlight_graphics__various__Line_1( itemRect ) );
       
  3654                     highlightRect.LayoutRect( itemRect,
       
  3655                         AKN_LAYOUT_WINDOW_Highlight_graphics__various__Line_2( itemRect ) );
       
  3656                     aGc.SetBrushStyle( CGraphicsContext::ESolidBrush );
       
  3657                     shadowRect.DrawRect( aGc );
       
  3658                     highlightRect.DrawRect( aGc );
       
  3659                     }
       
  3660 
       
  3661                 aGc.CancelClippingRect();
       
  3662 
       
  3663 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  3664                 if ( transApi )
       
  3665                     {
       
  3666                     transApi->StopDrawing();
       
  3667                     transApi->EndRedraw( MAknListBoxTfxInternal::EListHighlight );
       
  3668                     }
       
  3669 #endif
       
  3670                 }
       
  3671             break;
       
  3672             }
       
  3673         case ERemoveHighlight:
       
  3674         case ENoHighlight:
       
  3675         default:
       
  3676             break;
       
  3677         }
       
  3678 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  3679     if ( transApi )
       
  3680         {
       
  3681         transApi->BeginRedraw( MAknListBoxTfxInternal::EListItem, itemRect, aItem );
       
  3682         transApi->StartDrawing( MAknListBoxTfxInternal::EListItem );
       
  3683         }
       
  3684 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  3685 
       
  3686     // Partial items, so prevent drawing over the edge of menu pane
       
  3687 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  3688     if ( !transApi || ( transApi && transApi->EffectsDisabled() ) )
       
  3689         {
       
  3690         aGc.SetClippingRect(menuPaneRect.Rect());
       
  3691         }
       
  3692 #else
       
  3693     aGc.SetClippingRect(menuPaneRect.Rect());
       
  3694 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  3695 
       
  3696     // Cascade
       
  3697     if ( cascade )
       
  3698         {
       
  3699         TAknWindowLineLayout elementCascade( AknLayoutScalable_Avkon::list_single_pane_cp2_g3().LayoutLine());
       
  3700         TAknLayoutRect cascadeRect;
       
  3701         cascadeRect.LayoutRect( itemRect, elementCascade );
       
  3702         aGc.SetBrushStyle( CGraphicsContext::ENullBrush );
       
  3703         CAknsMaskedBitmapItemData* itemData = static_cast<CAknsMaskedBitmapItemData*>(
       
  3704             skin->GetCachedItemData( KAknsIIDQgnIndiSubmenu, EAknsITMaskedBitmap ) );
       
  3705         if( itemData )
       
  3706             {
       
  3707             aGc.BitBltMasked( cascadeRect.Rect().iTl, itemData->Bitmap(),
       
  3708                 cascadeRect.Rect().Size(), itemData->Mask(), ETrue );
       
  3709             }
       
  3710         else
       
  3711             {
       
  3712             aGc.BitBltMasked( cascadeRect.Rect().iTl, iExtension->iCascadeBitmap,
       
  3713                 cascadeRect.Rect().Size(), iExtension->iCascadeBitmapMask, ETrue );
       
  3714             }
       
  3715         }
       
  3716     else
       
  3717         {
       
  3718         TAknLayoutRect activeApplicationsIconRect;
       
  3719         activeApplicationsIconRect.LayoutRect( itemRect,
       
  3720             AknLayoutScalable_Avkon::list_single_pane_g1_cp2(0).LayoutLine() );
       
  3721         item->DrawItemIcon( aGc, activeApplicationsIconRect.Rect(), EFalse, 0);
       
  3722         }
       
  3723 
       
  3724     if ( hasIcon )
       
  3725         {
       
  3726         TAknLayoutRect iconLayoutRect;
       
  3727         iconLayoutRect.LayoutRect( itemRect,
       
  3728             AknLayoutScalable_Avkon::list_single_popup_submenu_pane_g1().LayoutLine() );
       
  3729 
       
  3730         TRect iconRect = iconLayoutRect.Rect();
       
  3731 
       
  3732         // radio button group
       
  3733         if ( iExtension->iHasRadioGroup )
       
  3734             {
       
  3735             if( IsItemMemberOfRadioButtonGroup(aItem) )
       
  3736                 {
       
  3737                 if ( iExtension->iSelectedRadioButtonItem == KNoSelectedRadioButtonItem &&
       
  3738                     item->iData.iFlags&EEikMenuItemRadioStart )
       
  3739                     {
       
  3740                     // just to be sure that some radio button is set on
       
  3741                     iExtension->iSelectedRadioButtonItem = aItem;
       
  3742                     }
       
  3743 
       
  3744                 if ( aItem == iExtension->iSelectedRadioButtonItem )
       
  3745                     {
       
  3746                     // draw radio button
       
  3747                     aGc.SetBrushStyle( CGraphicsContext::ENullBrush );
       
  3748                     CAknsMaskedBitmapItemData* itemData = static_cast<CAknsMaskedBitmapItemData*>(
       
  3749                         skin->GetCachedItemData( KAknsIIDQgnIndiRadiobuttOn, EAknsITMaskedBitmap ) );
       
  3750                     CFbsBitmap* radioButtonBmp = iExtension->iRadioButtonBitmap;
       
  3751                     CFbsBitmap* radioButtonMask = iExtension->iRadioButtonBitmapMask;
       
  3752                     if( itemData )
       
  3753                         {
       
  3754                         radioButtonBmp = itemData->Bitmap();
       
  3755                         radioButtonMask = itemData->Mask();
       
  3756                         }
       
  3757                     if( radioButtonBmp && radioButtonMask )
       
  3758                         {
       
  3759                         AknIconUtils::SetSize( radioButtonBmp,  iconRect.Size() );
       
  3760                         aGc.BitBltMasked( iconRect.iTl, radioButtonBmp,
       
  3761                             iconRect.Size(), radioButtonMask, ETrue );
       
  3762                         }
       
  3763                     }
       
  3764                 }
       
  3765             }
       
  3766         else if ( item->iData.iFlags&EEikMenuItemSymbolOn )
       
  3767             // draw check mark
       
  3768             {
       
  3769             aGc.SetBrushStyle( CGraphicsContext::ENullBrush );
       
  3770             CAknsMaskedBitmapItemData* itemData = static_cast<CAknsMaskedBitmapItemData*>(
       
  3771                 skin->GetCachedItemData( KAknsIIDQgnIndiMarkedAdd, EAknsITMaskedBitmap ) );
       
  3772             CFbsBitmap* checkMarkBmp = iExtension->iCheckMarkBitmap;
       
  3773             CFbsBitmap* checkMarkMask = iExtension->iCheckMarkBitmapMask;
       
  3774             if( itemData )
       
  3775                 {
       
  3776                 checkMarkBmp = itemData->Bitmap();
       
  3777                 checkMarkMask = itemData->Mask();
       
  3778                 }
       
  3779             if( checkMarkBmp && checkMarkMask )
       
  3780                 {
       
  3781                 AknIconUtils::SetSize( checkMarkBmp,  iconRect.Size() );
       
  3782                 aGc.BitBltMasked( iconRect.iTl, checkMarkBmp,
       
  3783                     iconRect.Size(), checkMarkMask, ETrue );
       
  3784                 }
       
  3785             }
       
  3786         }
       
  3787 
       
  3788     // Text
       
  3789     TAknLayoutText textRect( iExtension->GetMenuItemTextLayout( itemRect, cascade ) );
       
  3790     TRgb textColor = textRect.Color();
       
  3791     if ( aHighlight == EDrawHighlight ) // highlighted text
       
  3792         {
       
  3793         AknsUtils::GetCachedColor( skin, textColor, KAknsIIDQsnTextColors, EAknsCIQsnTextColorsCG10 );
       
  3794         }
       
  3795     else if ( !iOwner ) // menu
       
  3796         {
       
  3797         AknsUtils::GetCachedColor( skin, textColor, KAknsIIDQsnTextColors, EAknsCIQsnTextColorsCG19 );
       
  3798         }
       
  3799     else // submenu
       
  3800         {
       
  3801         AknsUtils::GetCachedColor( skin, textColor, KAknsIIDQsnTextColors, EAknsCIQsnTextColorsCG20 );
       
  3802         }
       
  3803 
       
  3804     //when OOM, the background is White, if the font's color is white, hardcode it to black
       
  3805     if( !background && aHighlight != EDrawHighlight )
       
  3806         {
       
  3807         const TInt KRate = 95;    // 95% similar rate
       
  3808         const TInt KFullColor = 255;
       
  3809         TInt redcolor = textColor.Red();
       
  3810         TInt bluecolor = textColor.Blue();
       
  3811         TInt greencolor = textColor.Green();
       
  3812         // test if the color is too similar to white color
       
  3813         if ( redcolor > KFullColor * KRate / 100 || 
       
  3814              bluecolor > KFullColor * KRate / 100 || 
       
  3815              greencolor > KFullColor * KRate / 100 )
       
  3816             {
       
  3817             textColor = KRgbBlack;
       
  3818             }
       
  3819        }
       
  3820     aGc.SetBrushStyle( CGraphicsContext::ENullBrush );
       
  3821     aGc.SetPenColor( textColor );
       
  3822     aGc.UseFont( textRect.Font() );
       
  3823 
       
  3824     const CFont* font = textRect.Font();
       
  3825 
       
  3826     //TBuf<CEikMenuPaneItem::SData::ENominalTextLength + KAknBidiExtraSpacePerLine> visualText; // buffer for visually ordered text
       
  3827     TBuf<255 + KAknBidiExtraSpacePerLine> visualText; // buffer for visually ordered text
       
  3828 
       
  3829     TInt clipWidth = textRect.TextRect().Width();
       
  3830 
       
  3831     AknBidiTextUtils::ConvertToVisualAndClip(
       
  3832         item->ScaleableText(),
       
  3833         visualText,
       
  3834         *font,
       
  3835         clipWidth,
       
  3836         clipWidth );
       
  3837 
       
  3838     textRect.DrawText( aGc, visualText, EFalse, textColor );
       
  3839     
       
  3840     // calculate demarcation rectangle for cascaded menu item
       
  3841     if (iCascadeMenuPane)
       
  3842         {
       
  3843         TPoint position( PositionRelativeToScreen() );
       
  3844         TRect cascRect( textRect.TextRect() );
       
  3845         cascRect.Move( position );
       
  3846         iExtension->iCascadeDRect.SetRect( cascRect.iTl, cascRect.iBr );        
       
  3847         }
       
  3848 
       
  3849     if(iExtension->iIsPenEnable)
       
  3850         {
       
  3851         TAknLayoutRect highlightRect;
       
  3852         highlightRect.LayoutRect( itemRect,
       
  3853             AKN_LAYOUT_WINDOW_Highlight_graphics__various__Line_2( itemRect ) );
       
  3854 
       
  3855         // store the calculated y-position to the menu item,
       
  3856         // so that it can be used in HandlePointerEventL()
       
  3857         item->iPos = highlightRect.Rect().iTl.iY;
       
  3858         aGc.DiscardFont();
       
  3859         }
       
  3860 
       
  3861     if ( !drawingInitiated )
       
  3862         {
       
  3863         Window().EndRedraw();
       
  3864         }
       
  3865 
       
  3866     aGc.CancelClippingRect();
       
  3867 
       
  3868 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  3869     if ( transApi && !transApi->EffectsDisabled() )
       
  3870         {
       
  3871         transApi->StopDrawing();
       
  3872         transApi->EndRedraw( MAknListBoxTfxInternal::EListItem, aItem );
       
  3873         iExtension->iGc->Deactivate();
       
  3874         }
       
  3875 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  3876     }
       
  3877 
       
  3878 
       
  3879 // -----------------------------------------------------------------------------
       
  3880 // CEikMenuPane::Draw
       
  3881 // -----------------------------------------------------------------------------
       
  3882 //
       
  3883 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  3884 EXPORT_C void CEikMenuPane::Draw( const TRect& aRect ) const
       
  3885     {
       
  3886     CWindowGc& gc = ( iExtension && iExtension->iGc ) ?
       
  3887                     *iExtension->iGc : SystemGc();
       
  3888     MAknListBoxTfxInternal *transApi = CAknListLoader::TfxApiInternal( &gc );
       
  3889 
       
  3890     if ( transApi )
       
  3891         {
       
  3892         iExtension->iGc->Activate( *DrawableWindow() );
       
  3893         
       
  3894         if ( !transApi->EffectsDisabled() )
       
  3895             {
       
  3896             if ( iExtension->iScrollBarRect.iTl.iX <= aRect.iTl.iX &&
       
  3897                  iExtension->iScrollBarRect.iBr.iX >= aRect.iBr.iX )
       
  3898                 {
       
  3899                 transApi->BeginRedraw( MAknListBoxTfxInternal::EListUpdateRect, aRect );
       
  3900                 iExtension->iGc->Deactivate();
       
  3901                 return;
       
  3902                 }
       
  3903         
       
  3904             iExtension->CalcItemSize( transApi );
       
  3905             }
       
  3906         }
       
  3907 #else
       
  3908 EXPORT_C void CEikMenuPane::Draw(const TRect& /*aRect*/) const
       
  3909     {
       
  3910 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  3911 
       
  3912     TRect windowRect( Rect() );
       
  3913     MAknsSkinInstance* skin = AknsUtils::SkinInstance();
       
  3914     MAknsControlContext* cc = NULL;
       
  3915 
       
  3916     if( iExtension )
       
  3917         {
       
  3918         cc = iExtension->iBgContext;
       
  3919         }
       
  3920 
       
  3921 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  3922     if ( transApi )
       
  3923         {
       
  3924         transApi->SetListType( MAknListBoxTfxInternal::EListBoxTypeMenuPane );
       
  3925         transApi->BeginRedraw( MAknListBoxTfxInternal::EListView, windowRect );
       
  3926         }
       
  3927 #else
       
  3928     CWindowGc& gc = SystemGc();
       
  3929 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  3930     PrepareGcForDrawingItems( gc );
       
  3931 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  3932     if ( transApi )
       
  3933         {
       
  3934         transApi->StartDrawing( MAknListBoxTfxInternal::EListView );
       
  3935         }
       
  3936 #endif
       
  3937 
       
  3938     if ( !IsCascadeMenuPane() )
       
  3939         {
       
  3940         CFbsBitmap* cbaExtension = AknsUtils::GetCachedBitmap( skin, KAknsIIDQsnBgSlicePopup );
       
  3941         if ( cbaExtension )
       
  3942             {
       
  3943             TAknLayoutRect sliceRect;
       
  3944             sliceRect.LayoutRect( windowRect, SkinLayout::Popup_windows_skin_placing__background_slice__Line_2() );
       
  3945             AknIconUtils::SetSize( cbaExtension, sliceRect.Rect().Size() );
       
  3946             gc.BitBlt( TPoint( windowRect.iTl.iX, windowRect.iBr.iY-cbaExtension->SizeInPixels().iHeight ), cbaExtension );
       
  3947             windowRect.iBr.iY -=2; // two used as margin when rect layouts were done
       
  3948             }
       
  3949         }
       
  3950 
       
  3951     TInt count=0;
       
  3952     if( iItemArray )
       
  3953         {
       
  3954         count=iItemArray->Count();
       
  3955         }
       
  3956 
       
  3957     // Give the topmost menu item's rect to SCT if needed.
       
  3958     if ( iExtension->iSct )
       
  3959         {
       
  3960         TAknLayoutRect listScrollPaneRect;
       
  3961         TAknLayoutRect menuPaneRect;
       
  3962         TAknLayoutRect singleMenuPaneRect;
       
  3963 
       
  3964         TAknWindowLineLayout listScrollPaneLayout( 
       
  3965             AknLayoutScalable_Avkon::listscroll_menu_pane(0).LayoutLine() );
       
  3966         if ( iExtension )
       
  3967             {
       
  3968             iExtension->AdjustPopupLayoutData( listScrollPaneLayout );
       
  3969             }
       
  3970         listScrollPaneRect.LayoutRect( windowRect, listScrollPaneLayout );
       
  3971         menuPaneRect.LayoutRect( listScrollPaneRect.Rect(),
       
  3972              AknLayoutScalable_Avkon::list_menu_pane( 0 ).LayoutLine() );
       
  3973         singleMenuPaneRect.LayoutRect( menuPaneRect.Rect(),
       
  3974              AknLayoutScalable_Avkon::list_single_pane_cp2( 0 ).LayoutLine() );
       
  3975         // Give the rect of the first menu item to SCT.
       
  3976         iExtension->iSct->SetMenuSctRect( singleMenuPaneRect.Rect() );
       
  3977 #ifdef RD_UI_TRANSITION_EFFECTS_LIST      
       
  3978         if( transApi )
       
  3979             {
       
  3980             iExtension->iSctRect = singleMenuPaneRect.Rect();
       
  3981             TAknLayoutRect cellLayRect;
       
  3982             cellLayRect.LayoutRect( iExtension->iSctRect,
       
  3983                 AknLayoutScalable_Avkon::cell_graphic_popup_pane( 0, 0, 0 ) );
       
  3984             iExtension->iSctRect.iTl.iX -= 1;
       
  3985             iExtension->iSctRect.iTl.iY -= 1;
       
  3986             iExtension->iSctRect.iBr.iX += 3;
       
  3987             transApi->ResetNonDrawingRects();
       
  3988             transApi->AddNonDrawingRect( iExtension->iScrollBarRect );
       
  3989             transApi->AddNonDrawingRect( iExtension->iSctRect );
       
  3990             }
       
  3991 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  3992         }
       
  3993 
       
  3994     if ( iExtension->iSct )
       
  3995         {
       
  3996         TRegionFix<4> region;
       
  3997         region.AddRect( Rect() );
       
  3998         region.SubRect( iExtension->iSct->Rect() );
       
  3999         gc.SetClippingRegion( region );
       
  4000         }
       
  4001         
       
  4002     TRect backgroundRect( iOwner ? windowRect : iExtension->GetBackgroundRect( windowRect ) );
       
  4003         
       
  4004     // The added flag removes the white bg for transparency
       
  4005     TBool frameDrawn = AknsDrawUtils::Background( 
       
  4006         skin, cc, this, gc, backgroundRect, KAknsDrawParamNoClearUnderImage );        
       
  4007 
       
  4008 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  4009     if ( transApi )
       
  4010         {
       
  4011         transApi->StopDrawing();
       
  4012         }
       
  4013 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  4014 
       
  4015     iExtension->iFullRedraw = ETrue;   
       
  4016 
       
  4017     for ( TInt ii=0;ii<count;++ii )
       
  4018         {
       
  4019         if(!iExtension->iSctHighlighted && ii == iSelectedItem  )
       
  4020             DrawItem( gc, ii, EDrawHighlight);
       
  4021         else
       
  4022             DrawItem( gc, ii, ENoHighlight);
       
  4023         }    
       
  4024   
       
  4025     iExtension->iFullRedraw = EFalse;   
       
  4026 
       
  4027     if ( iExtension->iSct )
       
  4028         {
       
  4029 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  4030         if ( transApi )
       
  4031             {
       
  4032             transApi->StartDrawing( MAknListBoxTfxInternal::EListNotSpecified );
       
  4033             }
       
  4034 #endif
       
  4035         gc.CancelClippingRegion();
       
  4036 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  4037         if ( transApi )
       
  4038             {
       
  4039             transApi->StopDrawing();
       
  4040             }
       
  4041 #endif
       
  4042         }
       
  4043         
       
  4044 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  4045     if ( transApi )
       
  4046         {
       
  4047         transApi->EndViewRedraw( aRect );
       
  4048         iExtension->iGc->Deactivate();
       
  4049         }
       
  4050 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  4051     }
       
  4052 
       
  4053 
       
  4054 // -----------------------------------------------------------------------------
       
  4055 // CEikMenuPane::ReportSelectionMadeL
       
  4056 // -----------------------------------------------------------------------------
       
  4057 //
       
  4058 void CEikMenuPane::ReportSelectionMadeL( TBool aAbortTransition )
       
  4059     {
       
  4060     _AKNTRACE_FUNC_ENTER;
       
  4061     if( aAbortTransition )
       
  4062         {
       
  4063         GfxTransEffect::Abort();
       
  4064         }
       
  4065     if ( !iItemArray || iItemArray->Count() == 0 )
       
  4066         {
       
  4067         return;
       
  4068         }
       
  4069 
       
  4070     if ( iCascadeMenuPane )
       
  4071         {
       
  4072         SetFocus( EFalse, EDrawNow );
       
  4073         iCascadeMenuPane->SetFocus( ETrue, EDrawNow );
       
  4074         return;
       
  4075         }
       
  4076 
       
  4077     // means the cascade created on the down event is getting the up event
       
  4078     if ( iSelectedItem == ENothingSelected && !iExtension->iSctHighlighted)
       
  4079         {
       
  4080         return;
       
  4081         }
       
  4082 
       
  4083     CEikMenuPaneItem* item = NULL;
       
  4084 
       
  4085     // the sct highlight does not have index so do not try to get item with the index
       
  4086     if(iSelectedItem != ENothingSelected)
       
  4087         item = (*iItemArray)[iSelectedItem];
       
  4088 
       
  4089     if ( item && item->iData.iFlags&EEikMenuItemDimmed )
       
  4090         {
       
  4091         iMenuObserver->HandleAttemptDimmedSelectionL( item->iData.iCommandId );
       
  4092         }
       
  4093     else
       
  4094         {
       
  4095         TInt commandId = 0;
       
  4096         if ( iExtension->iSctHighlighted )
       
  4097             {
       
  4098             commandId = EAknCmdEditMenuSctSelected;
       
  4099             }
       
  4100         else if (item && !item->iData.iCascadeId)
       
  4101             {
       
  4102             commandId = item->iData.iCommandId;
       
  4103             }
       
  4104 
       
  4105         if ( commandId == EAknCmdTaskSwapper )
       
  4106             {
       
  4107             if ( !iExtension->iTaskSwapIdle->IsActive() )
       
  4108                 {
       
  4109                 iExtension->iTaskSwapIdle->Start( TCallBack( TaskSwapCallBack ) );
       
  4110                 }
       
  4111             }
       
  4112 
       
  4113         if ( !commandId ) return; // Nothing to process
       
  4114 
       
  4115         if ( iEditMenuObserver )
       
  4116             iEditMenuObserver->ProcessCommandL( commandId );
       
  4117 
       
  4118         // have to save pointer now because in case if we are in a submenu
       
  4119         // 'this' might be destroyed by calling iMenuObserver->ProcessCommandL(
       
  4120         // commandId ), so need to avoid crash
       
  4121         CEikMenuPane* menu = iOwner ? iOwner : this;
       
  4122         MCoeControlObserver* observer = menu->Observer();
       
  4123 
       
  4124 
       
  4125         if ( commandId != EAknCmdTaskSwapper )
       
  4126             {
       
  4127             _AKNTRACE( "commandId = %d",  commandId );
       
  4128             iMenuObserver->ProcessCommandL( commandId ); 
       
  4129             }
       
  4130         else
       
  4131             {
       
  4132             ReportCanceled();
       
  4133             return;
       
  4134             }
       
  4135 
       
  4136         // very important for the context sensitive menu because it will
       
  4137         // be closed only after this call.
       
  4138         if ( this && observer )
       
  4139             {
       
  4140             observer->HandleControlEventL( menu,
       
  4141                 MCoeControlObserver::EEventRequestExit );
       
  4142             }
       
  4143 
       
  4144         MEikMenuObserver* fepMenuObserver =  CAknEnv::Static()->FepMenuObserver();
       
  4145         if ( fepMenuObserver )
       
  4146             {
       
  4147             fepMenuObserver->ProcessCommandL( commandId );
       
  4148             }
       
  4149         }
       
  4150     _AKNTRACE_FUNC_EXIT;
       
  4151     }
       
  4152 
       
  4153 
       
  4154 // -----------------------------------------------------------------------------
       
  4155 // CEikMenuPane::FocusChanged
       
  4156 // -----------------------------------------------------------------------------
       
  4157 //
       
  4158 EXPORT_C void CEikMenuPane::FocusChanged( TDrawNow aDrawNow )
       
  4159     {
       
  4160     _AKNTRACE_FUNC_ENTER;
       
  4161     _AKNTRACE( "aDrawNow =  %d", aDrawNow );
       
  4162     if( iExtension )
       
  4163         {
       
  4164         if ( IsFocused() )
       
  4165             {
       
  4166 #ifdef RD_UI_TRANSITION_EFFECTS_LIST        
       
  4167             // Focus must be handled here, otherwise it will come to late
       
  4168             MAknListBoxTfxInternal *transApi = CAknListLoader::TfxApiInternal( iExtension->iGc );
       
  4169     
       
  4170             if ( transApi )
       
  4171                 {
       
  4172                 transApi->HandleFocusChange( ETrue );
       
  4173                 }
       
  4174 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  4175             iExtension->FocusGained();
       
  4176             }
       
  4177         else // Not focused
       
  4178             {
       
  4179             iExtension->FocusLost();
       
  4180             }
       
  4181         }
       
  4182 
       
  4183     if ( !iItemArray || iItemArray->Count() == 0 )
       
  4184         {
       
  4185         return;
       
  4186         }
       
  4187     
       
  4188     if ( aDrawNow && iExtension->HighlightEnabled() )
       
  4189         {
       
  4190         // if focused or if current item is a cascade draw highlight (only draw if item is selected)
       
  4191         if ( iSelectedItem != ENothingSelected )
       
  4192             {
       
  4193             const CEikMenuPaneItem* item = (*iItemArray)[iSelectedItem];
       
  4194             THighlightType highlight = ERemoveHighlight;
       
  4195 
       
  4196             if ( !iExtension->iSctHighlighted && 
       
  4197                  ( item->iData.iCascadeId || IsFocused() ) )
       
  4198                 {
       
  4199                 PrepareHighlightFrame();
       
  4200                 highlight = EDrawHighlight;
       
  4201                 }
       
  4202 
       
  4203             DrawItem( iSelectedItem, highlight);
       
  4204             }
       
  4205         }
       
  4206     _AKNTRACE_FUNC_EXIT;
       
  4207     }
       
  4208 
       
  4209 // -----------------------------------------------------------------------------
       
  4210 // CEikMenuPane::IsHotKeyL
       
  4211 // -----------------------------------------------------------------------------
       
  4212 //
       
  4213 TBool CEikMenuPane::IsHotKeyL( const TInt modifiers, const TInt code )
       
  4214     {
       
  4215     if ( iHotKeyTable )
       
  4216         {
       
  4217         const TInt command = iHotKeyTable->CommandIdFromHotKey( code,modifiers );
       
  4218         if ( command )
       
  4219             {
       
  4220             if ( iMenuObserver->CheckHotKeyNotDimmedL( command) )
       
  4221                 {
       
  4222                 // have to save pointer now because in case if we are in a submenu
       
  4223                 // 'this' might be destroyed by calling iMenuObserver->ProcessCommandL(
       
  4224                 // commandId ), so need to avoid crash
       
  4225                 CEikMenuPane* menu = iOwner ? iOwner : this;
       
  4226                 MCoeControlObserver* observer = menu->Observer();
       
  4227 
       
  4228                 iMenuObserver->ProcessCommandL( command );
       
  4229 
       
  4230                 // very important for the context sensitive menu because it will
       
  4231                 // be closed only after this call.
       
  4232                 if ( this && observer )
       
  4233                     {
       
  4234                     observer->HandleControlEventL( menu,
       
  4235                         MCoeControlObserver::EEventRequestExit );
       
  4236                     }
       
  4237                 }
       
  4238             else
       
  4239                 {
       
  4240                 iMenuObserver->HandleAttemptDimmedSelectionL( command );
       
  4241                 }
       
  4242             return ETrue;
       
  4243             }
       
  4244         }
       
  4245     return EFalse;
       
  4246     }
       
  4247 
       
  4248 // -----------------------------------------------------------------------------
       
  4249 // CEikMenuPane::OfferKeyEventL
       
  4250 // -----------------------------------------------------------------------------
       
  4251 //
       
  4252 EXPORT_C TKeyResponse CEikMenuPane::OfferKeyEventL( const TKeyEvent& aKeyEvent, TEventCode aType )
       
  4253     { // if were on the control stack then consume all keys
       
  4254     return OfferKeyEventL( aKeyEvent, aType, ETrue );
       
  4255     }
       
  4256 
       
  4257 // -----------------------------------------------------------------------------
       
  4258 // CEikMenuPane::OfferKeyEventL
       
  4259 // -----------------------------------------------------------------------------
       
  4260 //
       
  4261 EXPORT_C TKeyResponse CEikMenuPane::OfferKeyEventL( const TKeyEvent& aKeyEvent, TEventCode aType, TBool aConsumeAllKeys )
       
  4262     { 
       
  4263     _AKNTRACE_FUNC_ENTER;
       
  4264     // Key event handling for scroll physics   
       
  4265     // Don't react to shift keys
       
  4266     if ( aKeyEvent.iScanCode == EStdKeyLeftShift ||
       
  4267          aKeyEvent.iScanCode == EStdKeyRightShift )
       
  4268         {
       
  4269         if ( aConsumeAllKeys )
       
  4270             {
       
  4271             _AKNTRACE( "[%s]", "OfferKeyEventL return 1" );
       
  4272             _AKNTRACE_FUNC_EXIT; 
       
  4273             return EKeyWasConsumed;
       
  4274             }
       
  4275         else
       
  4276             {
       
  4277             _AKNTRACE( "[%s]", "OfferKeyEventL return 2" );
       
  4278             _AKNTRACE_FUNC_EXIT;
       
  4279             return EKeyWasNotConsumed;
       
  4280             }
       
  4281         }
       
  4282     // Disable key events when panning
       
  4283     if ( iExtension->iPanningActive || 
       
  4284          iExtension->iPhysics->OngoingPhysicsAction() 
       
  4285          == CAknPhysics::EAknPhysicsActionBouncing )
       
  4286         { 
       
  4287         _AKNTRACE( "[%s]", "OfferKeyEventL return 3" );
       
  4288         _AKNTRACE_FUNC_EXIT;
       
  4289         return EKeyWasConsumed;         
       
  4290         }
       
  4291     if ( iExtension->iFlickActive )
       
  4292         { 
       
  4293         // Stop physics engine when key down event occurs.     
       
  4294         iExtension->iPhysics->StopPhysics();
       
  4295         iExtension->iPhysics->ResetFriction();
       
  4296         iExtension->iFlickActive = EFalse;
       
  4297         iExtension->iKeyEventActive = ETrue;
       
  4298         _AKNTRACE( "[%s]", "OfferKeyEventL return 4" );
       
  4299         _AKNTRACE_FUNC_EXIT;
       
  4300         return EKeyWasConsumed;                  
       
  4301         }
       
  4302     else if ( iExtension->iKeyEventActive && aType != EEventKeyDown )
       
  4303         {
       
  4304         // Consume following events until next key down.
       
  4305         _AKNTRACE( "[%s]", "OfferKeyEventL return 5" );
       
  4306         _AKNTRACE_FUNC_EXIT;
       
  4307         return EKeyWasConsumed;
       
  4308         }
       
  4309     else
       
  4310         {
       
  4311         // Next key down after stopping flick, it is ok to continue.
       
  4312         iExtension->iKeyEventActive = EFalse;
       
  4313         }
       
  4314         
       
  4315     // Restore possible panning offset
       
  4316     if (iExtension->Offset() != 0 )
       
  4317         {
       
  4318         iExtension->RestoreOffset( aKeyEvent.iCode );
       
  4319         }       
       
  4320           
       
  4321     CheckCreateScrollerL();
       
  4322     const TInt modifiers = ( aKeyEvent.iModifiers )&( EModifierCtrl|EModifierShift|EModifierPureKeycode );
       
  4323     const TInt code = aKeyEvent.iCode;
       
  4324     TKeyResponse keyResponse = EKeyWasNotConsumed;
       
  4325     if ( iCascadeMenuPane )
       
  4326         {
       
  4327         keyResponse = iCascadeMenuPane->OfferKeyEventL( aKeyEvent, aType, EFalse );
       
  4328         if ( keyResponse == EKeyWasNotConsumed &&
       
  4329             ( code==EKeyEscape || (!AknLayoutUtils::LayoutMirrored() && code==EKeyLeftArrow) || ( AknLayoutUtils::LayoutMirrored() && code==EKeyRightArrow) ) )
       
  4330             {
       
  4331             // show transition only when "canceling" the cascade menu
       
  4332             // choosing an item from cascade does not execute effect
       
  4333             iExtension->iShowCascadeTransition = ETrue;
       
  4334             CloseCascadeMenu();
       
  4335             //Fixed for TSW errors DLAN-7SFH86.
       
  4336             IgnoreEventsUntilNextPointerUp();            
       
  4337             keyResponse = EKeyWasConsumed;
       
  4338             }
       
  4339         _AKNTRACE( "[%s]", "OfferKeyEventL return 6" );
       
  4340         _AKNTRACE_FUNC_EXIT;
       
  4341         return keyResponse;
       
  4342         }
       
  4343 
       
  4344     // with single click first key event enables highlight
       
  4345     if ( !iExtension->HighlightEnabled() )
       
  4346         {
       
  4347         if ( code == EKeyUpArrow || code == EKeyDownArrow ||
       
  4348              code == EKeyEnter || code == EKeyOK )
       
  4349             {
       
  4350             iExtension->SetDefaultHighlight();
       
  4351             return EKeyWasConsumed;
       
  4352             }
       
  4353         }    
       
  4354 
       
  4355     // if popup menu displaying, needs to check for hotkeys itself.
       
  4356     if ( IsHotKeyL( modifiers, code ) )
       
  4357         return EKeyWasConsumed;
       
  4358     TInt count = 0;
       
  4359     if( iItemArray )
       
  4360         count = iItemArray->Count();
       
  4361     if ( count == 0 )
       
  4362         {
       
  4363         _AKNTRACE( "[%s]", "OfferKeyEventL return 8" );
       
  4364         _AKNTRACE_FUNC_EXIT;
       
  4365         return EKeyWasNotConsumed;
       
  4366         }
       
  4367     const TInt max = count-1;
       
  4368     TInt newHighlight = iSelectedItem;
       
  4369     TBool loopScrolling = ETrue;
       
  4370     TInt itemAfterLastItem = loopScrolling ? 0 : max;
       
  4371     TInt itemAfterFirstItem = loopScrolling ? max : 0;
       
  4372 
       
  4373 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  4374     CWindowGc& gc = iExtension->iGc ? *iExtension->iGc : SystemGc();
       
  4375     MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( &gc );
       
  4376 #endif //RD_UI_TRANSITION_EFFECTS_LIST
       
  4377 
       
  4378     if(iExtension->iIsPenEnable)
       
  4379         {
       
  4380         _AKNTRACE( "[%s]", "iExtension->iIsPenEnable = TRUE" );
       
  4381         // Scroll highlighted item so that it becomes visible,
       
  4382         // if it is not visible before (scrolling with scroll bar
       
  4383         // can cause highlighted item to go out of screen)
       
  4384         TInt topItem = iScroller->TopItemIndex();
       
  4385         TInt bottomItem = topItem + NumberOfItemsThatFitInView();
       
  4386               
       
  4387         if ( iExtension->Offset() < 0 ) 
       
  4388             {
       
  4389             // Extra bottom item when panning
       
  4390             bottomItem++;
       
  4391             }
       
  4392         
       
  4393         if( bottomItem > NumberOfItemsInPane() )
       
  4394             {
       
  4395             bottomItem = NumberOfItemsInPane();
       
  4396             }
       
  4397         _AKNTRACE( "topItem = %d,bottomItem = %d", topItem,bottomItem );
       
  4398 
       
  4399         if ( aType != EEventKeyDown && iSelectedItem != ENothingSelected &&
       
  4400             !(iExtension->iSctHighlighted && topItem == 0) &&
       
  4401             (iSelectedItem < topItem || iSelectedItem > bottomItem - 1) )
       
  4402             {
       
  4403             _AKNTRACE( "[%s]", "ScrollToMakeItemVisible(iSelectedItem);" );
       
  4404             ScrollToMakeItemVisible(iSelectedItem);
       
  4405 
       
  4406             ActivateGc();
       
  4407 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  4408             if ( transApi )
       
  4409                 {
       
  4410                 iExtension->iGc->Activate( *DrawableWindow() );
       
  4411                 }
       
  4412 #else
       
  4413             CWindowGc& gc = SystemGc();
       
  4414 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  4415             PrepareGcForDrawingItems( gc );
       
  4416 
       
  4417             // draw all items that are needed.
       
  4418             for( TInt i = 0; i < count; i++ )
       
  4419                 {
       
  4420                 if( i == iSelectedItem && !iExtension->iSctHighlighted)
       
  4421                     {
       
  4422                     DrawItem( gc, i, EDrawHighlight );
       
  4423                     }
       
  4424                 else
       
  4425                     {
       
  4426                     DrawItem( gc, i, ERemoveHighlight );
       
  4427                     }
       
  4428                 }
       
  4429 
       
  4430 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  4431             if ( transApi )
       
  4432                 {
       
  4433                 iExtension->iGc->Deactivate();
       
  4434                 }
       
  4435 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  4436             DeactivateGc();
       
  4437             _AKNTRACE( "[%s]", "OfferKeyEventL return 9" );
       
  4438             _AKNTRACE_FUNC_EXIT;
       
  4439             return EKeyWasConsumed;
       
  4440             }
       
  4441         }
       
  4442 
       
  4443     if ( iSelectedItem != ENothingSelected || iExtension->iSctHighlighted )
       
  4444         {
       
  4445         switch ( code )
       
  4446             {
       
  4447             case EKeySpace:
       
  4448             	_AKNTRACE( "[%s]", "OfferKeyEventL(EKeySpace)" );
       
  4449                 iEikonEnv->InfoMsg( R_EIK_TBUF_PRESS_SPACE_MENP );
       
  4450                 _AKNTRACE( "[%s]", "OfferKeyEventL return 10" );
       
  4451                 _AKNTRACE_FUNC_EXIT;
       
  4452                 return EKeyWasConsumed;
       
  4453 // AKNLAF start
       
  4454 // loop scrolling always used in options menus
       
  4455             case EKeyDownArrow:
       
  4456             	_AKNTRACE( "[%s]", "OfferKeyEventL(EKeyDownArrow)" );
       
  4457 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  4458                 if ( transApi )
       
  4459                     {
       
  4460                     transApi->SetMoveType(
       
  4461                             MAknListBoxTfxInternal::EListMoveDown );
       
  4462                     }
       
  4463 #endif //RD_UI_TRANSITION_EFFECTS_LIST
       
  4464                 if ( iExtension->iSctHighlighted && iExtension->iSct )
       
  4465                     {
       
  4466                     iExtension->iSctHighlighted = EFalse;
       
  4467                     MoveHighlightTo( ++newHighlight );
       
  4468                     iExtension->iSct->HighlightSctRow( iExtension->iSctHighlighted );
       
  4469                     }
       
  4470                 else
       
  4471                     {
       
  4472                     if ( iSelectedItem == max  && iExtension->iSct)
       
  4473                         {
       
  4474                         // If SCT exists, it gets the highlight
       
  4475                         // if moving from the bottom item
       
  4476                         iExtension->iSctHighlighted = ETrue;
       
  4477                         MoveHighlightTo( ENothingSelected );
       
  4478                         iExtension->iSct->HighlightSctRow( iExtension->iSctHighlighted );
       
  4479                         }
       
  4480                     else
       
  4481                         {
       
  4482                         MoveHighlightTo( ++newHighlight>max? itemAfterLastItem: newHighlight );
       
  4483                         }
       
  4484                     }
       
  4485                 keyResponse = EKeyWasConsumed;
       
  4486                 break;
       
  4487             case EKeyUpArrow:
       
  4488             	_AKNTRACE( "[%s]", "OfferKeyEventL(EKeyUpArrow)" );
       
  4489 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  4490                 if ( transApi )
       
  4491                     {
       
  4492                     transApi->SetMoveType(
       
  4493                             MAknListBoxTfxInternal::EListMoveUp );
       
  4494                     }
       
  4495 #endif //RD_UI_TRANSITION_EFFECTS_LIST
       
  4496                 if ( iExtension->iSct &&
       
  4497                     iSelectedItem == 0 && !iExtension->iSctHighlighted )
       
  4498                     {
       
  4499                     iExtension->iSctHighlighted = ETrue;
       
  4500                     MoveHighlightTo( ENothingSelected );
       
  4501                     iExtension->iSct->HighlightSctRow( iExtension->iSctHighlighted );
       
  4502                     }
       
  4503                 else if ( iExtension->iSctHighlighted && iExtension->iSct )
       
  4504                     {
       
  4505                     iExtension->iSctHighlighted = EFalse;
       
  4506                     MoveHighlightTo( itemAfterFirstItem );
       
  4507                     iExtension->iSct->HighlightSctRow( iExtension->iSctHighlighted );
       
  4508                     }
       
  4509                 else
       
  4510                     {
       
  4511                     MoveHighlightTo( --newHighlight<0?
       
  4512                                 itemAfterFirstItem: newHighlight );
       
  4513                     }
       
  4514                 keyResponse = EKeyWasConsumed;
       
  4515                 break;
       
  4516 // AKNLAF end
       
  4517             case EKeyRightArrow :
       
  4518             case EKeyLeftArrow :
       
  4519                 {
       
  4520                 _AKNTRACE( "[%s]", "OfferKeyEventL(EKeyRightArrow or EKeyLeftArrow)" );
       
  4521                 if( count == 0 ) // Implies empty or undefined item array
       
  4522                     {
       
  4523                     if ( aConsumeAllKeys )
       
  4524                         return EKeyWasConsumed;
       
  4525                     return EKeyWasNotConsumed;
       
  4526                     }
       
  4527                 if ( iExtension->iSctHighlighted && iExtension->iSct )
       
  4528                     {
       
  4529                     return iExtension->iSct->OfferKeyEventL( aKeyEvent, aType );
       
  4530                     }
       
  4531                 const CEikMenuPaneItem* item = (*iItemArray)[iSelectedItem];
       
  4532 
       
  4533                 if ( item->iData.iCascadeId && iExtension->HighlightEnabled() )
       
  4534                     {
       
  4535                     if ( ( !AknLayoutUtils::LayoutMirrored() && code == EKeyRightArrow ) ||
       
  4536                         ( AknLayoutUtils::LayoutMirrored() && code == EKeyLeftArrow ) )
       
  4537                         {
       
  4538                         TryLaunchCascadeMenuL( *item );
       
  4539 
       
  4540                         if ( iCascadeMenuPane )
       
  4541                             {
       
  4542                             iCascadeMenuPane->iExtension->SetDefaultHighlight();
       
  4543                             }
       
  4544 
       
  4545                         keyResponse = EKeyWasConsumed;
       
  4546                         break;
       
  4547                         } // else fall through
       
  4548                     } // else fall through
       
  4549                 }
       
  4550             case EKeyHome:
       
  4551             case EKeyEnd:
       
  4552                 {
       
  4553                 _AKNTRACE( "[%s]", "OfferKeyEventL(EKeyHome or EKeyEnd)" );
       
  4554                 // only popup menu panes should consume these keys. ???
       
  4555                 if ( aConsumeAllKeys )
       
  4556                         return EKeyWasConsumed;
       
  4557                 return EKeyWasNotConsumed;
       
  4558                 }
       
  4559             case EKeyEnter:
       
  4560             case EKeyOK:
       
  4561             case EAknSoftkeySelect:
       
  4562             case EAknSoftkeyOk:
       
  4563 
       
  4564                 {
       
  4565                 _AKNTRACE( "[%s]", "OfferKeyEventL(EKeyEnter,EKeyOK,EAknSoftkeySelect,EAknSoftkeyOk)" );
       
  4566                 if ( iExtension->iSctHighlighted && iExtension->iSct )
       
  4567                     {
       
  4568                     keyResponse = iExtension->iSct->OfferKeyEventL( aKeyEvent, aType );
       
  4569                     if ( keyResponse == EKeyWasConsumed )
       
  4570                         {
       
  4571                         ReportSelectionMadeL();
       
  4572                         break;
       
  4573                         }
       
  4574                     }
       
  4575                 if ( modifiers&( EModifierShift|EModifierCtrl|EModifierFunc ) )
       
  4576                     return EKeyWasConsumed;
       
  4577                 if ( aKeyEvent.iRepeats )
       
  4578                     return EKeyWasConsumed;
       
  4579                 if ( count == 0 ) // Do the same as modifiers (implies empty or undefined item array)
       
  4580                     return EKeyWasConsumed;
       
  4581                 CEikMenuPaneItem* item = (*iItemArray)[iSelectedItem];
       
  4582                 if ( item->iData.iCascadeId )
       
  4583                     {
       
  4584                     TryLaunchCascadeMenuL( *item );
       
  4585                     if ( iCascadeMenuPane )
       
  4586                         {
       
  4587                         iCascadeMenuPane->iExtension->SetDefaultHighlight();
       
  4588                         }
       
  4589                     }
       
  4590                 else
       
  4591                     ReportSelectionMadeL();
       
  4592                 return EKeyWasConsumed;
       
  4593                 }
       
  4594             case '4':// These are for menu sct.
       
  4595             case '5':
       
  4596             case '6':
       
  4597                 {
       
  4598                 _AKNTRACE( "[%s]", "OfferKeyEventL('4','5','6')" );
       
  4599                 if ( iExtension->iSctHighlighted && iExtension->iSct )
       
  4600                     {
       
  4601                     return iExtension->iSct->OfferKeyEventL( aKeyEvent, aType );
       
  4602                     }
       
  4603                 else
       
  4604                     {
       
  4605                     return EKeyWasNotConsumed;
       
  4606                     }
       
  4607                 }
       
  4608 
       
  4609             default:
       
  4610                 break;
       
  4611             }
       
  4612         }
       
  4613 
       
  4614     switch ( code )
       
  4615         {
       
  4616         case EKeyMenu:
       
  4617         	_AKNTRACE( "[%s]", "OfferKeyEventL(EKeyMenu)" );
       
  4618             iMenuObserver->HandleSideBarMenuL( 0, TPoint( 0, 0 ), modifiers, iHotKeyTable );
       
  4619             return EKeyWasConsumed;
       
  4620         case EKeyEscape:
       
  4621         	_AKNTRACE( "[%s]", "OfferKeyEventL(EKeyEscape)" );
       
  4622             if ( iOwner )
       
  4623                 return EKeyWasNotConsumed; // owner will destroy the cascade
       
  4624             ReportCanceled();
       
  4625             return EKeyWasConsumed;
       
  4626         default:
       
  4627             break;
       
  4628             }
       
  4629 
       
  4630     if ( MoveToItemL( code, modifiers) )
       
  4631     	{
       
  4632         _AKNTRACE( "[%s]", "OfferKeyEventL return 11" );
       
  4633     	 _AKNTRACE_FUNC_EXIT; 
       
  4634     	 return EKeyWasConsumed;  // must return here because in the case of a cascade it will have been deleted by now.
       
  4635     	}
       
  4636 
       
  4637     if ( aConsumeAllKeys )
       
  4638     	{
       
  4639     	_AKNTRACE( "[%s]", "OfferKeyEventL return 12" );
       
  4640     	 _AKNTRACE_FUNC_EXIT; 
       
  4641         return EKeyWasConsumed;
       
  4642     	}
       
  4643 
       
  4644     else
       
  4645     	{
       
  4646     	_AKNTRACE( "[%s]", "OfferKeyEventL return 13" );
       
  4647     	 _AKNTRACE_FUNC_EXIT; 
       
  4648         return keyResponse;
       
  4649     	}
       
  4650     }
       
  4651 
       
  4652 
       
  4653 // -----------------------------------------------------------------------------
       
  4654 // CEikMenuPane::NavigateToNextItem
       
  4655 // New for AVKON
       
  4656 // -----------------------------------------------------------------------------
       
  4657 //
       
  4658 EXPORT_C void CEikMenuPane::NavigateToNextItem()
       
  4659     {
       
  4660     if ( iCascadeMenuPane )
       
  4661         iCascadeMenuPane->NavigateToNextItem();
       
  4662     else
       
  4663         {
       
  4664         const TInt max = NumberOfItemsInPane() - 1;
       
  4665         TInt newHighlight = SelectedItem();
       
  4666         MoveHighlightTo( ( ++newHighlight > max ) ? 0 : newHighlight);
       
  4667         }
       
  4668     }
       
  4669 
       
  4670 
       
  4671 // ---------------------------------------------------------------------------
       
  4672 // Activates the currently highlighted item.
       
  4673 // ---------------------------------------------------------------------------
       
  4674 //
       
  4675 void CEikMenuPane::ActivateCurrentItemL()
       
  4676     {
       
  4677     if ( !iExtension->HighlightEnabled() )
       
  4678         {
       
  4679         iExtension->SetDefaultHighlight();
       
  4680         return;
       
  4681         }
       
  4682     _AKNTRACE_FUNC_ENTER;
       
  4683 
       
  4684     if ( iExtension->iPanningActive || 
       
  4685            iExtension->iPhysics->OngoingPhysicsAction() 
       
  4686                == CAknPhysics::EAknPhysicsActionBouncing )
       
  4687         {
       
  4688         // Don't allow the item activation in kinetic scrolling enabled
       
  4689         // menus if menu is being dragged or bounce effect is in action.
       
  4690         // In this case the event is discarded.
       
  4691         _AKNTRACE( "[%s]" "ActivateCurrentItemL return 1" );
       
  4692         _AKNTRACE_FUNC_EXIT;
       
  4693         return;
       
  4694         }
       
  4695         
       
  4696     TInt count( NumberOfItemsInPane() );
       
  4697         
       
  4698     if ( iExtension->iIsPenEnable )
       
  4699         {
       
  4700         // Scroll highlighted item so that it becomes visible
       
  4701         // if it is not visible before (scrolling with scroll bar
       
  4702         // can cause highlighted item to go out of screen).
       
  4703         TInt topItem( iScroller->TopItemIndex() );
       
  4704         TInt bottomItem( topItem + NumberOfItemsThatFitInView() );
       
  4705         if ( bottomItem > count )
       
  4706             {
       
  4707             bottomItem = count;
       
  4708             }
       
  4709    
       
  4710         if ( iExtension->Offset() < 0 &&
       
  4711              ( iSelectedItem == topItem || iSelectedItem == bottomItem ) )
       
  4712             {
       
  4713             // Restoring offset with "simulated" ok key event.         
       
  4714             iExtension->RestoreOffset( EKeyOK ); 
       
  4715             }    
       
  4716         else if ( iSelectedItem < topItem ||
       
  4717                   iSelectedItem > bottomItem - 1 )
       
  4718             {
       
  4719             if ( count > iSelectedItem )
       
  4720                 {
       
  4721                 if ( iExtension->iSctHighlighted && iExtension->iSct )
       
  4722                     {
       
  4723                     TKeyEvent key;
       
  4724                     key.iCode = EKeyOK;
       
  4725                     key.iModifiers = 0;
       
  4726 
       
  4727                     TKeyResponse keyResponse( EKeyWasNotConsumed );
       
  4728                     TEventCode type( EEventNull );
       
  4729                     keyResponse = iExtension->iSct->OfferKeyEventL( key,
       
  4730                                                                     type );
       
  4731                     if ( keyResponse == EKeyWasConsumed )
       
  4732                         {
       
  4733                         ReportSelectionMadeL();
       
  4734                         }
       
  4735                     _AKNTRACE( "[%s]" "ActivateCurrentItemL return 2" );
       
  4736                     _AKNTRACE_FUNC_EXIT;
       
  4737                     return;
       
  4738                     }
       
  4739                 }
       
  4740 
       
  4741             iExtension->isUpdateScrollDirectly = ETrue;
       
  4742             ScrollToMakeItemVisible( iSelectedItem );
       
  4743             iExtension->isUpdateScrollDirectly = EFalse;
       
  4744 
       
  4745             ActivateGc();
       
  4746 
       
  4747 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  4748 
       
  4749             MAknListBoxTfxInternal *transApi =
       
  4750                 CAknListLoader::TfxApiInternal( iExtension->iGc );
       
  4751             if ( transApi )
       
  4752                 {
       
  4753                 iExtension->iGc->Activate( *DrawableWindow() );
       
  4754                 }
       
  4755             CWindowGc& gc = transApi ? *iExtension->iGc : SystemGc();
       
  4756 
       
  4757 #else
       
  4758 
       
  4759             CWindowGc& gc = SystemGc();
       
  4760 
       
  4761 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  4762 
       
  4763             PrepareGcForDrawingItems( gc );
       
  4764 
       
  4765             // Draw all items that are needed.
       
  4766             for ( TInt i = 0; i < count; i++ )
       
  4767                 {
       
  4768                 if ( i == iSelectedItem && !iExtension->iSctHighlighted )
       
  4769                     {
       
  4770                     DrawItem( gc, i, EDrawHighlight );
       
  4771                     }
       
  4772                 else
       
  4773                     {
       
  4774                     DrawItem( gc, i, ERemoveHighlight );
       
  4775                     }
       
  4776                 }
       
  4777 
       
  4778 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  4779 
       
  4780             if ( transApi )
       
  4781                 {
       
  4782                 iExtension->iGc->Deactivate();
       
  4783                 }
       
  4784 
       
  4785 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  4786 
       
  4787             DeactivateGc();
       
  4788             _AKNTRACE( "[%s]" "ActivateCurrentItemL return 3" );
       
  4789             _AKNTRACE_FUNC_EXIT;
       
  4790             return;
       
  4791             }
       
  4792         }
       
  4793 
       
  4794     if ( iCascadeMenuPane )
       
  4795         {
       
  4796         iCascadeMenuPane->ActivateCurrentItemL();
       
  4797         }
       
  4798     else
       
  4799         {
       
  4800         if ( count > iSelectedItem )
       
  4801             {
       
  4802             if ( iExtension->iSctHighlighted && iExtension->iSct )
       
  4803                 {
       
  4804                 TKeyEvent key;
       
  4805                 key.iCode = EKeyOK;
       
  4806                 key.iModifiers = 0;
       
  4807 
       
  4808                 TKeyResponse keyResponse( EKeyWasNotConsumed );
       
  4809                 TEventCode type( EEventNull );
       
  4810                 keyResponse = iExtension->iSct->OfferKeyEventL(
       
  4811                                                 key, type );
       
  4812                 if ( keyResponse == EKeyWasConsumed )
       
  4813                     {
       
  4814                     ReportSelectionMadeL();
       
  4815                     }
       
  4816                 }
       
  4817             else
       
  4818                 {
       
  4819                 CEikMenuPaneItem* item = (*iItemArray)[iSelectedItem];
       
  4820                 if ( item->iData.iCascadeId )
       
  4821                     {
       
  4822                     TryLaunchCascadeMenuL(*item);
       
  4823                     }
       
  4824                 else
       
  4825                     {
       
  4826                     ReportSelectionMadeL();
       
  4827                     }
       
  4828                 }
       
  4829             }
       
  4830         }
       
  4831     _AKNTRACE( "[%s]" "ActivateCurrentItemL return 4" );
       
  4832     _AKNTRACE_FUNC_EXIT;
       
  4833     }
       
  4834 
       
  4835 
       
  4836 // -----------------------------------------------------------------------------
       
  4837 // CEikMenuPane::CancelActiveMenuPane
       
  4838 // New for AVKON
       
  4839 // -----------------------------------------------------------------------------
       
  4840 //
       
  4841 TBool CEikMenuPane::CancelActiveMenuPane()
       
  4842     {
       
  4843     // If it is possible to close a cascade, return ETrue
       
  4844     if ( iCascadeMenuPane )
       
  4845         {
       
  4846         iCascadeMenuPane->CancelActiveMenuPane();
       
  4847         CloseCascadeMenu( ETrue );
       
  4848         return ETrue;
       
  4849         }
       
  4850     return EFalse;
       
  4851     }
       
  4852 
       
  4853 // -----------------------------------------------------------------------------
       
  4854 // CEikMenuPane::MoveToItemL
       
  4855 // -----------------------------------------------------------------------------
       
  4856 //
       
  4857 TBool CEikMenuPane::MoveToItemL(TInt /*aCode*/, TInt /*aMods*/)
       
  4858     {
       
  4859     return EFalse;
       
  4860     }
       
  4861 
       
  4862 // -----------------------------------------------------------------------------
       
  4863 // CEikMenuPane::ReportCanceled
       
  4864 // -----------------------------------------------------------------------------
       
  4865 //
       
  4866 void CEikMenuPane::ReportCanceled()
       
  4867     {
       
  4868 
       
  4869     // let menubar handle the cancel case so transition can be shown
       
  4870     // use "fake" pointer event
       
  4871     CEikMenuBar* menubar = static_cast<CEikMenuBar*>( Parent() );
       
  4872     if( menubar->MenuPane() == this )
       
  4873         {
       
  4874         TPointerEvent ptrEvent;
       
  4875         ptrEvent.iType = TPointerEvent::EButton1Up;
       
  4876         menubar->HandlePointerEventL( ptrEvent );
       
  4877         }
       
  4878     else
       
  4879         {
       
  4880         MCoeControlObserver* observer = iOwner ? iOwner->Observer() : Observer();
       
  4881         if ( observer )
       
  4882             {
       
  4883             // context sensitive menu
       
  4884             TRAP_IGNORE( observer->HandleControlEventL( iOwner ? iOwner : this,
       
  4885                 MCoeControlObserver::EEventRequestCancel ) );
       
  4886             }
       
  4887         else  
       
  4888             {
       
  4889             // application menu
       
  4890             TRAP_IGNORE( iMenuObserver->ProcessCommandL( EEikCmdCanceled ) );
       
  4891             }
       
  4892         }
       
  4893     }
       
  4894 
       
  4895 // -----------------------------------------------------------------------------
       
  4896 // CEikMenuPane::ExtensionInterface
       
  4897 // -----------------------------------------------------------------------------
       
  4898 //
       
  4899 EXPORT_C void* CEikMenuPane::ExtensionInterface( TUid /*aInterface*/ )
       
  4900     {
       
  4901     return NULL;
       
  4902     }
       
  4903 
       
  4904 // ----------------------------------------------------------------------------
       
  4905 // CEikMenuPane::HandlePointerEventL
       
  4906 //
       
  4907 // Handles pointer events.
       
  4908 // ----------------------------------------------------------------------------
       
  4909 //
       
  4910 EXPORT_C void CEikMenuPane::HandlePointerEventL( const TPointerEvent& aPointerEvent )
       
  4911     {
       
  4912     if( !AknLayoutUtils::PenEnabled() )
       
  4913         {
       
  4914         return;
       
  4915         }
       
  4916 
       
  4917     _AKNTRACE_FUNC_ENTER;
       
  4918 
       
  4919     if ( iOwner && !IsVisible() )
       
  4920         {
       
  4921         _AKNTRACE( "[%s]", "HandlePointerEventL return 1" );
       
  4922         _AKNTRACE_FUNC_EXIT;
       
  4923         return;
       
  4924         }
       
  4925     
       
  4926     TBool noSelection = EFalse;
       
  4927  
       
  4928     // get pointer grabber1
       
  4929     CCoeControl* grabberBefore = GrabbingComponent();
       
  4930     
       
  4931     TPointerEvent pointerEvent = aPointerEvent; 
       
  4932     iExtension->ChangePosition( pointerEvent );
       
  4933     iExtension->iLastPointerEvent = pointerEvent;
       
  4934     
       
  4935     // Send pointerevent to childs - not to scroll bar if a sub menu is open
       
  4936     TRect sbRect;
       
  4937     if ( iSBFrame->VerticalScrollBar() &&
       
  4938          iSBFrame->VScrollBarVisibility() == CEikScrollBarFrame::EOn )
       
  4939         {
       
  4940         sbRect = iSBFrame->VerticalScrollBar()->Rect();
       
  4941         }
       
  4942     if ( ! ( iCascadeMenuPane && sbRect.Contains( 
       
  4943               pointerEvent.iPosition ) ) )
       
  4944         {
       
  4945         _AKNTRACE( "[%s]", "CAknControl::HandlePointerEventL( pointerEvent );" );
       
  4946         CAknControl::HandlePointerEventL( pointerEvent );        
       
  4947         }    
       
  4948     else
       
  4949         {
       
  4950         if ( aPointerEvent.iType == TPointerEvent::EButton1Down )
       
  4951             {
       
  4952             if( AknLayoutUtils::PenEnabled() )
       
  4953                 {
       
  4954                 if ( CAknTransitionUtils::TransitionsEnabled( AknTransEffect::EComponentTransitionsOff ) )
       
  4955                     {
       
  4956                     iExtension->ImmediateFeedback( ETouchFeedbackDecreasingPopUp );
       
  4957                     }
       
  4958                 else
       
  4959                     {
       
  4960                     iExtension->ImmediateFeedback( ETouchFeedbackPopUp );
       
  4961                     }
       
  4962                 }
       
  4963             iExtension->iShowCascadeTransition = ETrue;
       
  4964             CloseCascadeMenu();  
       
  4965             IgnoreEventsUntilNextPointerUp();
       
  4966             _AKNTRACE( "[%s]", "HandlePointerEventL return 2" );
       
  4967             _AKNTRACE_FUNC_EXIT;
       
  4968             return;
       
  4969             }
       
  4970         }
       
  4971 
       
  4972     // get pointer grabber
       
  4973     CCoeControl* grabberAfter = GrabbingComponent();
       
  4974 
       
  4975     // if grabberBefore or grabberAfter, then some child is handling pointerevent.
       
  4976     if ( (grabberBefore || grabberAfter ) 
       
  4977          && ( !iExtension->iSct || iExtension->iScrollBarRect.Contains( pointerEvent.iPosition ) ) )
       
  4978         {
       
  4979         _AKNTRACE( "[%s]", "HandlePointerEventL return 3" );
       
  4980         _AKNTRACE_FUNC_EXIT;
       
  4981         return;
       
  4982         }
       
  4983     
       
  4984     // Forward pointer events to embedded CBA if sub menu open
       
  4985     if ( iExtension->iCba && iCascadeMenuPane )
       
  4986         {
       
  4987         TBool sendToCBA = EFalse;
       
  4988         // if embedded CBA is grabbing the pointer we send the events to it
       
  4989         if( iExtension->iDownOnCbaArea )
       
  4990             {
       
  4991             if( aPointerEvent.iType == TPointerEvent::EButton1Up )
       
  4992                 {
       
  4993                 iExtension->iDownOnCbaArea = EFalse;
       
  4994                 }
       
  4995             sendToCBA = ETrue;
       
  4996             }            
       
  4997         else 
       
  4998             {
       
  4999             TPoint pos ( 
       
  5000                 aPointerEvent.iPosition + PositionRelativeToScreen() );
       
  5001             TRect cbaRect ( iExtension->iCba->PositionRelativeToScreen(), 
       
  5002                             iExtension->iCba->Size() );
       
  5003             if ( cbaRect.Contains( pos ) && 
       
  5004                  aPointerEvent.iType == TPointerEvent::EButton1Down )
       
  5005                 {
       
  5006                 sendToCBA = ETrue;
       
  5007                 iExtension->iDownOnCbaArea = ETrue;
       
  5008                 }
       
  5009             }
       
  5010         iCascadeMenuPane->iExtension->iDownOnCbaArea 
       
  5011             = iExtension->iDownOnCbaArea;
       
  5012         
       
  5013         if ( sendToCBA )
       
  5014             {
       
  5015             // scale the pointer event coordinates relative to CBA
       
  5016             TPointerEvent event = aPointerEvent;
       
  5017             TPoint position( aPointerEvent.iPosition + 
       
  5018                     PositionRelativeToScreen() );
       
  5019             event.iPosition = (position - 
       
  5020                     iExtension->iCba->PositionRelativeToScreen());
       
  5021             // send the event to CBA
       
  5022             iExtension->iCba->HandlePointerEventL(event);          
       
  5023             _AKNTRACE( "[%s]", "HandlePointerEventL return 4" );
       
  5024             _AKNTRACE_FUNC_EXIT;
       
  5025             return;            
       
  5026             }
       
  5027         }
       
  5028     // Submenu of a submenu to forward events to cba
       
  5029     else if ( iCascadeMenuPane )
       
  5030         {
       
  5031         iCascadeMenuPane->iExtension->iDownOnCbaArea 
       
  5032             = iExtension->iDownOnCbaArea;
       
  5033         }
       
  5034     
       
  5035     // In sub menu and pointer down has come to cba area
       
  5036     if ( iOwner && iOwner->iExtension->iDownOnCbaArea )
       
  5037         {
       
  5038         TPointerEvent parentEvent;
       
  5039         iExtension->CalculateParentEvent(aPointerEvent, parentEvent);                                        
       
  5040         _AKNTRACE( "[%s]", "HandlePointerEventL return 5" );
       
  5041         _AKNTRACE_FUNC_EXIT;
       
  5042         return iOwner->HandlePointerEventL( parentEvent );
       
  5043         }
       
  5044 
       
  5045     // Rect whic contains only area of menu items.
       
  5046     const TRect innerRect = iBorder.InnerRect( Rect() );
       
  5047     TRect menuSctRect;
       
  5048     // Get the option item's rect in Menu SCT
       
  5049     if ( iExtension->iSct )
       
  5050         {
       
  5051         TAknLayoutRect menuPaneRect;
       
  5052         TAknWindowLineLayout menuPane;
       
  5053         
       
  5054         TAknWindowLineLayout listScrollPaneLayout( 
       
  5055             AknLayoutScalable_Avkon::listscroll_menu_pane(0).LayoutLine() );
       
  5056         if ( iExtension )
       
  5057             {
       
  5058             iExtension->AdjustPopupLayoutData( listScrollPaneLayout );
       
  5059             }
       
  5060         TAknLayoutRect listScrollPaneRect;
       
  5061         listScrollPaneRect.LayoutRect( Rect(), listScrollPaneLayout );
       
  5062         
       
  5063         menuPane = AknLayoutScalable_Avkon::list_menu_pane( 0 ).LayoutLine();
       
  5064         menuPaneRect.LayoutRect( listScrollPaneRect.Rect(), menuPane );
       
  5065         menuSctRect = menuPaneRect.Rect();
       
  5066         }
       
  5067     TRect cascadeMenuRect(0,0,0,0);
       
  5068 
       
  5069     // Y coordinate for pointer event
       
  5070     const TInt yPos = aPointerEvent.iPosition.iY;
       
  5071 
       
  5072 
       
  5073     // Get top and botton item indexes.
       
  5074     TInt topItem = iScroller->TopItemIndex();
       
  5075     TInt bottomItem = topItem + NumberOfItemsThatFitInView();
       
  5076   
       
  5077     if( iExtension->Offset() < 0 )
       
  5078         {
       
  5079         // Panning has happened so we have one extra item.
       
  5080         ++bottomItem;    
       
  5081         }
       
  5082 
       
  5083     if( bottomItem > NumberOfItemsInPane() )
       
  5084         {
       
  5085         bottomItem = NumberOfItemsInPane();
       
  5086         }
       
  5087 
       
  5088 
       
  5089     // if submenu, then move it's rect coordinates to relative to parent.
       
  5090     if ( iCascadeMenuPane  )
       
  5091         {
       
  5092         TPoint subPos = iCascadeMenuPane->PositionRelativeToScreen();
       
  5093         cascadeMenuRect = TRect(subPos-PositionRelativeToScreen(), iCascadeMenuPane->Size());
       
  5094         }
       
  5095 
       
  5096     // Pointerevent in case we need to pass event from submenu to parent
       
  5097     TPointerEvent parentEvent;   
       
  5098 
       
  5099     // Stop timers if dragged outside
       
  5100     if ( iExtension && iExtension->iDraggedOutside )
       
  5101         {
       
  5102         iExtension->StopCascadeMenuTimer();
       
  5103         iExtension->ResetPressedHighlight();
       
  5104         }
       
  5105 
       
  5106 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  5107     MAknListBoxTfxInternal *transApi = CAknListLoader::TfxApiInternal(
       
  5108                                                             iExtension->iGc );
       
  5109     TBool effects = transApi && !transApi->EffectsDisabled();
       
  5110 #endif
       
  5111 
       
  5112     switch (aPointerEvent.iType )
       
  5113         {
       
  5114         case TPointerEvent::EButton1Up:
       
  5115             {
       
  5116             _AKNTRACE( "[%s]", "TPointerEvent::EButton1Up" );
       
  5117             if ( !innerRect.Contains( aPointerEvent.iPosition ) ) 
       
  5118                 {
       
  5119                 // remove highlight in case highlight is outside of menu pane 
       
  5120                 iExtension->EnableHighlight( EFalse );
       
  5121                 if ( iOwner )
       
  5122                     {
       
  5123                     RepaintHighlight();
       
  5124                     }
       
  5125                 } 
       
  5126             if ( iOwner && 
       
  5127                  !innerRect.Contains( aPointerEvent.iPosition ) && 
       
  5128                  !iExtension->iDownOnMenuArea )
       
  5129                 {
       
  5130                 iExtension->CalculateParentEvent( aPointerEvent, parentEvent);
       
  5131                 _AKNTRACE( "[%s]", "HandlePointerEventL return 6" );
       
  5132                 _AKNTRACE_FUNC_EXIT;
       
  5133                 return iOwner->HandlePointerEventL( parentEvent );
       
  5134                 }
       
  5135             iExtension->iDownOnMenuArea = EFalse;
       
  5136 
       
  5137             iExtension->iPanningActive = EFalse;
       
  5138             if ( !(iExtension->iSct &&  iExtension->iSct->Rect().Contains( iExtension->iStartPoint ) ) )
       
  5139                 {
       
  5140                 TPoint drag = iExtension->iStartPoint - aPointerEvent.iPosition;
       
  5141                 if ( iExtension->iPhysics->StartPhysics( 
       
  5142                     drag, iExtension->iStartTime ) )
       
  5143                     {
       
  5144                     iExtension->iFlickActive = ETrue;
       
  5145                     iExtension->ResetPressedHighlight();
       
  5146                     }
       
  5147                 }
       
  5148             if ( iExtension->HighlightTimerActive() &&
       
  5149                  !iExtension->iPressedDown )
       
  5150                 {
       
  5151                 // Complete the timer here if it's still running
       
  5152                 // when up event is received.
       
  5153                 iExtension->ResetPressedHighlight();
       
  5154                 CEikMenuPaneExtension::HighlightTimerCallBack( iExtension );
       
  5155                 }
       
  5156                       
       
  5157             // in submenu and pointer lifted outside of x -limits : handle in parent
       
  5158             if ( iOwner && iOwner->IsFocused() && (aPointerEvent.iPosition.iX < innerRect.iTl.iX  ||
       
  5159                     aPointerEvent.iPosition.iX > innerRect.iBr.iX ))
       
  5160                 {
       
  5161                 iExtension->CalculateParentEvent( aPointerEvent, parentEvent);
       
  5162                 _AKNTRACE( "[%s]", "HandlePointerEventL return 7" );
       
  5163                 _AKNTRACE_FUNC_EXIT;
       
  5164                 return iOwner->HandlePointerEventL( parentEvent );
       
  5165                 }
       
  5166 
       
  5167             // if button up inside menu and over selected item, then do selection.
       
  5168             if (Extension()->iItemsReadyForPenSelection &&
       
  5169                 innerRect.Contains( aPointerEvent.iPosition ) )
       
  5170                 {
       
  5171                 
       
  5172                 if(iExtension->iSct && iExtension->iSct->Rect().Contains(aPointerEvent.iPosition) && iExtension->iSpecialCharPointed)
       
  5173                     {
       
  5174                     TKeyEvent key;
       
  5175                     key.iCode=EKeyOK;
       
  5176                     key.iModifiers=0;
       
  5177                     iExtension->iSct->OfferKeyEventL(key, EEventKey);
       
  5178                     iExtension->iSpecialCharPointed = EFalse;
       
  5179                     Extension()->iItemsReadyForPenSelection = EFalse;
       
  5180                     ReportSelectionMadeL();
       
  5181                     _AKNTRACE( "[%s]", "HandlePointerEventL return 8" );
       
  5182                     _AKNTRACE_FUNC_EXIT;
       
  5183                     return;
       
  5184                     }
       
  5185                 else if(iSelectedItem != ENothingSelected ) // beware out of indexing
       
  5186                     {
       
  5187                     if ( iItemArray->Count() == 0 )
       
  5188                         {
       
  5189                         _AKNTRACE( "[%s]", "HandlePointerEventL return 9" );
       
  5190                         _AKNTRACE_FUNC_EXIT;
       
  5191                         return;
       
  5192                         }
       
  5193                         
       
  5194                     TInt threshold = 0;
       
  5195                     threshold = iExtension->iPhysics->DragThreshold();
       
  5196                                           
       
  5197                     CEikMenuPaneItem* item = (*iItemArray)[iSelectedItem];
       
  5198                     if((yPos < item->iPos + iItemHeight + threshold ) &&
       
  5199                      ( yPos > item->iPos - threshold ) )
       
  5200                         {
       
  5201                         // if new item has submenu, show it                                         
       
  5202                         if ( item->iData.iCascadeId 
       
  5203                             && iSelectedItem == iExtension->iButtonDownItem )    
       
  5204                             {                              
       
  5205                             // close previous submenu if open
       
  5206                             if ( iCascadeMenuPane )
       
  5207                                 {
       
  5208                                 CloseCascadeMenu();
       
  5209                                 }                           
       
  5210                             iExtension->StopCascadeMenuTimer();
       
  5211                                                        
       
  5212                             iExtension->ResetPressedHighlight();
       
  5213                             
       
  5214                             // Up happened on partial item, it must be moved to be
       
  5215                             // fully visible before opening (possible) cascade menu.
       
  5216                             if( iSelectedItem == topItem ||
       
  5217                                 iSelectedItem == bottomItem - 1)
       
  5218                                 {
       
  5219                                 // Restoring physics offset with "simulated" ok key event                      
       
  5220                                 iExtension->RestoreOffset( EKeyOK );
       
  5221                                 }                                 
       
  5222                             MoveHighlightTo(iSelectedItem);
       
  5223                          
       
  5224                             TryLaunchCascadeMenuL( *item );
       
  5225                             }
       
  5226                         else if ( iExtension->iButtonDownItem == iSelectedItem )
       
  5227                             {
       
  5228                             iExtension->ImmediateFeedback( ETouchFeedbackList,
       
  5229                                                            ETouchFeedbackVibra );
       
  5230                             if( !IsCascadeMenuPane() )
       
  5231                                 {
       
  5232                                 // EFalse = don't stop transition if opening the cascade menu 
       
  5233                                 // just report selection
       
  5234                                 if ( ( !iExtension->iSct || ( iExtension->iSct && menuSctRect.Contains( aPointerEvent.iPosition ) ) )
       
  5235                                     && !iCascadeMenuPane && iExtension->iPressedDown )
       
  5236                                     {
       
  5237                                     Extension()->iItemsReadyForPenSelection = EFalse;
       
  5238                                     iExtension->ResetPressedHighlight();
       
  5239                                     ReportSelectionMadeL( EFalse );
       
  5240                                     _AKNTRACE( "[%s]", "HandlePointerEventL return 10" );
       
  5241                                     _AKNTRACE_FUNC_EXIT;
       
  5242                                     return;
       
  5243                                     }                            
       
  5244                                 }
       
  5245                             else
       
  5246                                 {
       
  5247                                 if ( !iExtension->iSct || ( iExtension->iSct && menuSctRect.Contains(aPointerEvent.iPosition) ) 
       
  5248                                      && iExtension->iPressedDown )
       
  5249                                     {
       
  5250                                     Extension()->iItemsReadyForPenSelection = EFalse;
       
  5251                                     iExtension->ResetPressedHighlight();
       
  5252                                     ReportSelectionMadeL();
       
  5253                                     _AKNTRACE( "[%s]", "HandlePointerEventL return 11" );
       
  5254                                     _AKNTRACE_FUNC_EXIT;
       
  5255                                     return;
       
  5256                                     }
       
  5257                                 }
       
  5258                             }
       
  5259                         }
       
  5260                     }
       
  5261                 }
       
  5262                                            
       
  5263             iExtension->ResetPressedHighlight();
       
  5264             iExtension->iButtonDownItem = KErrNotFound;
       
  5265             if ( iExtension->iNextHighlightItem != KErrNotFound )
       
  5266                 {
       
  5267                 MoveHighlightTo( iExtension->iNextHighlightItem );
       
  5268                 iExtension->iNextHighlightItem = KErrNotFound;
       
  5269                 }  
       
  5270             }
       
  5271             break;
       
  5272         case TPointerEvent::EButton1Down:
       
  5273             {
       
  5274             _AKNTRACE( "[%s]", "TPointerEvent::EButton1Down" );
       
  5275             iExtension->iNextHighlightItem = KErrNotFound;
       
  5276 
       
  5277             // Start drag
       
  5278             if( innerRect.Contains( aPointerEvent.iPosition ) )
       
  5279                 {
       
  5280                 if ( iExtension->iFlickActive )
       
  5281                     {
       
  5282                     noSelection = ETrue;
       
  5283 					//when touch down during the flicking, play a basic list feedback
       
  5284                     iExtension->ImmediateFeedback( ETouchFeedbackList );
       
  5285                     }
       
  5286                 // stop physics for drag
       
  5287                 iExtension->iPhysics->StopPhysics();
       
  5288                 iExtension->iPhysics->ResetFriction();
       
  5289                 
       
  5290                 iExtension->iStartPoint = aPointerEvent.iPosition;
       
  5291                 iExtension->iPrevPoint = iExtension->iStartPoint;
       
  5292                 iExtension->iStartTime.HomeTime();          
       
  5293                 }                                             
       
  5294       
       
  5295             if ( !noSelection ) 
       
  5296                 {
       
  5297                 Extension()->iItemsReadyForPenSelection = ETrue;
       
  5298                 }
       
  5299             if ( innerRect.Contains( aPointerEvent.iPosition ) )
       
  5300                 {
       
  5301                 iExtension->iDownOnMenuArea = ETrue;
       
  5302                 if ( !noSelection ) 
       
  5303                     {
       
  5304                     iExtension->EnableHighlight( ETrue, ETrue );
       
  5305                     }
       
  5306                 if ( iCascadeMenuPane )
       
  5307                     {
       
  5308                     // if submenu, and clicked outside of it
       
  5309                     if ( !cascadeMenuRect.Contains( aPointerEvent.iPosition ) )
       
  5310                         {
       
  5311                         if( AknLayoutUtils::PenEnabled() )
       
  5312                             {                            
       
  5313                             if ( CAknTransitionUtils::TransitionsEnabled( AknTransEffect::EComponentTransitionsOff ) )
       
  5314                                 {
       
  5315                                 iExtension->ImmediateFeedback( ETouchFeedbackDecreasingPopUp );
       
  5316                                 }
       
  5317                             else
       
  5318                                 {
       
  5319                                 iExtension->ImmediateFeedback( ETouchFeedbackPopUp );
       
  5320                                 }
       
  5321                             }
       
  5322                         //Just close sub menu
       
  5323                         iExtension->iShowCascadeTransition = ETrue;
       
  5324                         CloseCascadeMenu();
       
  5325                         iExtension->EnableHighlight( EFalse );
       
  5326                         RepaintHighlight();
       
  5327                         IgnoreEventsUntilNextPointerUp();                                                                  
       
  5328                         break;
       
  5329                         }
       
  5330                     }
       
  5331                 else
       
  5332                     {
       
  5333                     // menu sct
       
  5334                     if(iExtension->iSct&& !iExtension->iSctHighlighted && iExtension->iSct->Rect().Contains(aPointerEvent.iPosition))
       
  5335                         {
       
  5336                         iExtension->iSctHighlighted = ETrue;
       
  5337                         iExtension->iSct->HighlightSctRow( iExtension->iSctHighlighted );
       
  5338                         MoveHighlightTo( ENothingSelected ); // from other highlight to sct
       
  5339                         }
       
  5340                     // Act in the rect of option items
       
  5341                     else if (!iExtension->iSct || (iExtension->iSct && menuSctRect.Contains(aPointerEvent.iPosition)))
       
  5342                         {
       
  5343                         // Scroll only through visible items
       
  5344                         for ( TInt ii = topItem; ii < bottomItem; ++ii )
       
  5345                             {     
       
  5346                             CEikMenuPaneItem* item = (*iItemArray)[ii];
       
  5347 
       
  5348                             // if this item is clicked
       
  5349                             if ((yPos < item->iPos + iItemHeight) &&
       
  5350                                 (yPos > item->iPos))
       
  5351                                 {
       
  5352                                 if(iExtension->iSctHighlighted && iExtension->iSct && menuSctRect.Contains(aPointerEvent.iPosition))
       
  5353                                     {
       
  5354                                     // from sct to normal menu item
       
  5355                                     iExtension->iSctHighlighted = EFalse;
       
  5356                                     iExtension->iSct->HighlightSctRow( iExtension->iSctHighlighted );
       
  5357                                     }
       
  5358 
       
  5359 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  5360                                 if ( effects )
       
  5361                                     {
       
  5362                                     transApi->SetMoveType( MAknListBoxTfxInternal::EListTap );
       
  5363                                     }
       
  5364 #endif
       
  5365                                 iExtension->iPressedDown = ETrue;
       
  5366 
       
  5367                                 // Start timer for pressed highlight
       
  5368                                 if ( !noSelection )
       
  5369                                     {
       
  5370                                     iExtension->ImmediateFeedback( ETouchFeedbackList );
       
  5371                                     iExtension->StartHighlightTimerL();
       
  5372                                     }
       
  5373                                 iExtension->iNextHighlightItem = ii;
       
  5374                                 iExtension->iButtonDownItem = ii;
       
  5375                                 
       
  5376                                 // down even on already highlighted item => list feedback
       
  5377                                 if ( iExtension->iButtonDownItem == iSelectedItem )
       
  5378                                     {
       
  5379                                     iExtension->ImmediateFeedback( ETouchFeedbackList );
       
  5380                                     }
       
  5381                                 if ( noSelection )
       
  5382                                     {
       
  5383                                     iExtension->iButtonDownItem = KErrNotFound;
       
  5384                                     }
       
  5385 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  5386                                 if ( effects )
       
  5387                                     {
       
  5388                                     transApi->Draw( Rect() );
       
  5389                                     }
       
  5390 #endif
       
  5391                                 // if new item has submenu, show it
       
  5392                                 if ( item->iData.iCascadeId )
       
  5393                                     {
       
  5394                                     if ( !iExtension->IsCascadeMenuTimerActive() )
       
  5395                                         {
       
  5396                                         iExtension->StartCascadeMenuTimerL();
       
  5397                                         }   
       
  5398                                     }
       
  5399                                 // item found, then break looping
       
  5400                                 break;
       
  5401                                 }
       
  5402                             }
       
  5403                         }
       
  5404                     }
       
  5405                 }
       
  5406             else
       
  5407                 {
       
  5408                 // Clicked out side submenu, parent handles this
       
  5409                 if ( iOwner )
       
  5410                     {
       
  5411                     iExtension->CalculateParentEvent(aPointerEvent, parentEvent);                                        
       
  5412                     _AKNTRACE( "[%s]", "HandlePointerEventL return 12" );
       
  5413                     _AKNTRACE_FUNC_EXIT;
       
  5414                     return iOwner->HandlePointerEventL( parentEvent );
       
  5415                     }
       
  5416                 else
       
  5417                     {
       
  5418                     if ( iExtension->iIsPenEnable ) 
       
  5419                         {
       
  5420                         // For finger usability, extend to the right.
       
  5421                         TRect innerToRightRect;
       
  5422                         if ( AknLayoutUtils::LayoutMirrored() )
       
  5423                             {
       
  5424                             innerToRightRect = TRect( Rect().iTl, innerRect.iBr );
       
  5425                             }
       
  5426                         else
       
  5427                             {
       
  5428                             innerToRightRect = TRect( innerRect.iTl, Rect().iBr );
       
  5429                             }
       
  5430                         // Keep opened
       
  5431                         if ( innerToRightRect.Contains( aPointerEvent.iPosition ) ) 
       
  5432                             {
       
  5433                             break;
       
  5434                             }
       
  5435                         }
       
  5436                     // clicked outside, then close menu case by case
       
  5437                     if ( iCascadeMenuPane )
       
  5438                         {
       
  5439                         if( AknLayoutUtils::PenEnabled() )
       
  5440                             {                            
       
  5441                             if ( CAknTransitionUtils::TransitionsEnabled( AknTransEffect::EComponentTransitionsOff ) )
       
  5442                                 {
       
  5443                                 iExtension->ImmediateFeedback( ETouchFeedbackDecreasingPopUp );
       
  5444                                 }
       
  5445                             else
       
  5446                                 {
       
  5447                                 iExtension->ImmediateFeedback( ETouchFeedbackPopUp );
       
  5448                                 }
       
  5449                             }
       
  5450                         iExtension->iShowCascadeTransition = ETrue;
       
  5451                         CloseCascadeMenu(); //Just close sub menu.
       
  5452                         iExtension->EnableHighlight( EFalse );
       
  5453                         RepaintHighlight();
       
  5454                         IgnoreEventsUntilNextPointerUp();
       
  5455                         }
       
  5456                     else
       
  5457                         {
       
  5458                         ReportCanceled();   //Close main menu.
       
  5459                         }
       
  5460                     }
       
  5461                 }
       
  5462 
       
  5463             }
       
  5464             break;
       
  5465 
       
  5466         case TPointerEvent::EButtonRepeat:
       
  5467         case TPointerEvent::EDrag:
       
  5468             {                    
       
  5469             _AKNTRACE( "[%s]", "TPointerEvent::EDrag" );
       
  5470             // In submenu and drag outside and down didn't come to menu
       
  5471             if ( iOwner && 
       
  5472                  !iExtension->iDownOnMenuArea && 
       
  5473                  !innerRect.Contains( aPointerEvent.iPosition ) )
       
  5474                 {
       
  5475                 iExtension->CalculateParentEvent( aPointerEvent, parentEvent);
       
  5476                 _AKNTRACE( "[%s]", "HandlePointerEventL return 13" );
       
  5477                 _AKNTRACE_FUNC_EXIT;
       
  5478                 return iOwner->HandlePointerEventL( parentEvent );
       
  5479                 }
       
  5480 
       
  5481             if ( ( iExtension->iSct )
       
  5482             		&& ( iExtension->iSct->Rect().Contains( iExtension->iStartPoint ) ) )
       
  5483             	{
       
  5484             	break;
       
  5485             	}
       
  5486             
       
  5487             TPoint drag = iExtension->iStartPoint - 
       
  5488                 aPointerEvent.iPosition;
       
  5489             TInt threshold = drag.iY;      
       
  5490             if( Abs( threshold ) > iExtension->iPhysics->DragThreshold() )
       
  5491                 {
       
  5492                 iExtension->iButtonDownItem = KErrNotFound;
       
  5493                 iExtension->ResetPressedHighlight();
       
  5494                 iExtension->iNextHighlightItem = KErrNotFound;
       
  5495                 iExtension->iPanningActive = ETrue;
       
  5496                 iExtension->EnableHighlight( EFalse );
       
  5497 
       
  5498 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  5499                 MAknListBoxTfx* tfxApi = CAknListLoader::TfxApi( iExtension->iGc );
       
  5500 
       
  5501                 if ( tfxApi )
       
  5502                     {
       
  5503                     tfxApi->EnableEffects( EFalse );
       
  5504                     }
       
  5505 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  5506                 }    
       
  5507                          
       
  5508             if ( iExtension->iPanningActive )
       
  5509                 {
       
  5510                 TPoint delta( 
       
  5511                     0, iExtension->iPrevPoint.iY - aPointerEvent.iPosition.iY );
       
  5512                 iExtension->iPhysics->RegisterPanningPosition( delta );
       
  5513                 } 
       
  5514             iExtension->iPrevPoint = aPointerEvent.iPosition;                                                     
       
  5515 
       
  5516             // in submenu and pointer dragged outside of x -limits : handle in parent
       
  5517             if ( iOwner && ((aPointerEvent.iPosition.iX < innerRect.iTl.iX ) ||
       
  5518                    ( aPointerEvent.iPosition.iX > innerRect.iBr.iX )))
       
  5519                 {
       
  5520                 iExtension->CalculateParentEvent(aPointerEvent, parentEvent);     
       
  5521                 iExtension->iButtonDownItem = KErrNotFound;
       
  5522                 iExtension->ResetPressedHighlight();
       
  5523                 }
       
  5524        
       
  5525             // act in Menu Sct or Option Menu repectively
       
  5526             if (( iExtension->iSct && menuSctRect.Contains(aPointerEvent.iPosition)) ||
       
  5527                 ( !iExtension->iSct && innerRect.Contains(aPointerEvent.iPosition)))
       
  5528                {
       
  5529                 iExtension->iDraggedOutside = EFalse;
       
  5530                 // Scroll only through visible items
       
  5531                 for ( TInt ii = topItem; ii < bottomItem; ++ii )
       
  5532                     {
       
  5533                     CEikMenuPaneItem* item = (*iItemArray)[ii];
       
  5534 
       
  5535                     // if item is searched item.
       
  5536                     if ( (yPos < item->iPos + iItemHeight) && (yPos
       
  5537                             > item->iPos) )
       
  5538                         {
       
  5539                         if ( iCascadeMenuPane )
       
  5540                             {
       
  5541                             // if submenu open and touched item is not the one which opened submenu, then close submenu
       
  5542                             if ( (ii != iSelectedItem)
       
  5543                                     && !cascadeMenuRect.Contains(
       
  5544                                             aPointerEvent.iPosition ) )
       
  5545                                 {
       
  5546                                 if ( AknLayoutUtils::PenEnabled() )
       
  5547                                     {
       
  5548                                     if ( CAknTransitionUtils::TransitionsEnabled(
       
  5549                                             AknTransEffect::EComponentTransitionsOff ) )
       
  5550                                         {
       
  5551                                         iExtension->ImmediateFeedback(
       
  5552                                                 ETouchFeedbackDecreasingPopUp );
       
  5553                                         }
       
  5554                                     else
       
  5555                                         {
       
  5556                                         iExtension->ImmediateFeedback(
       
  5557                                                 ETouchFeedbackPopUp );
       
  5558                                         }
       
  5559                                     }
       
  5560                                 iExtension->iShowCascadeTransition = ETrue;
       
  5561                                 CloseCascadeMenu();
       
  5562                                 }
       
  5563                             }
       
  5564                         else
       
  5565                             {
       
  5566                             TInt oldSelected = iSelectedItem;
       
  5567                             // update highlight to new item
       
  5568                             if ( oldSelected != ii )
       
  5569                                 {
       
  5570                                 iExtension->iPressedDown = EFalse;
       
  5571 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  5572                                 if ( effects
       
  5573                                         && !iExtension->iShowCascadeTransition )
       
  5574                                     {
       
  5575                                     transApi->SetMoveType(
       
  5576                                             MAknListBoxTfxInternal::EListDrag );
       
  5577                                     }
       
  5578 #endif
       
  5579                                 }
       
  5580                             TRect screenRect( TPoint( KMinTInt, KMinTInt ),
       
  5581                                     TPoint( KMaxTInt, KMaxTInt ) );
       
  5582                             TRect repeatRect( screenRect.iTl.iX, item->iPos,
       
  5583                                     screenRect.iBr.iX, item->iPos
       
  5584                                             + iItemHeight );
       
  5585                             }
       
  5586                         // item found, break                      
       
  5587                         break;
       
  5588                         }
       
  5589                     }
       
  5590 
       
  5591                 }
       
  5592             }
       
  5593             break;
       
  5594 
       
  5595         default:
       
  5596             break;
       
  5597         }
       
  5598     _AKNTRACE( "[%s]", "HandlePointerEventL return 16" );
       
  5599     _AKNTRACE_FUNC_EXIT;
       
  5600     }
       
  5601 
       
  5602 // -----------------------------------------------------------------------------
       
  5603 // CEikMenuPane::InputCapabilities
       
  5604 // Returns the input capabilites of the menu pane which accepts all text.
       
  5605 //
       
  5606 // @since ER5U
       
  5607 // -----------------------------------------------------------------------------
       
  5608 //
       
  5609 EXPORT_C TCoeInputCapabilities CEikMenuPane::InputCapabilities() const
       
  5610     {
       
  5611     return TCoeInputCapabilities( TCoeInputCapabilities::EAllText ); // Max length parameter removed for release15
       
  5612     }
       
  5613 
       
  5614 
       
  5615 // -----------------------------------------------------------------------------
       
  5616 // CEikMenuPane::AddMenuItemL
       
  5617 // Adds a new menu item to the menu pane by creating a new menu item, setting its data to aMenuItem
       
  5618 // and appending it to the pane's menu item array. Updates the menu's scroll bar to take acount of the
       
  5619 // new item.
       
  5620 // SData is a structure so all fields in it should be set to avoid any unexpected behaviour.
       
  5621 // -----------------------------------------------------------------------------
       
  5622 //
       
  5623 EXPORT_C void CEikMenuPane::AddMenuItemL( const CEikMenuPaneItem::SData& aMenuItem )
       
  5624 // For use by Menu extensions
       
  5625     {
       
  5626     if ( !iItemArray )
       
  5627         CreateItemArrayL();
       
  5628     CEikMenuPaneItem* item = new(ELeave) CEikMenuPaneItem();
       
  5629     item->iData = aMenuItem;
       
  5630     iItemArray->AddItemL( item );
       
  5631     UpdateScrollBar();
       
  5632     }
       
  5633 
       
  5634 // -----------------------------------------------------------------------------
       
  5635 // CEikMenuPane::AddMenuItemL
       
  5636 // -----------------------------------------------------------------------------
       
  5637 //
       
  5638 EXPORT_C void CEikMenuPane::AddMenuItemL(const CEikMenuPaneItem::SData& aMenuItem, TInt aPreviousId)
       
  5639     {
       
  5640     if ( !iItemArray )
       
  5641         CreateItemArrayL();
       
  5642     CEikMenuPaneItem* item = new(ELeave) CEikMenuPaneItem();
       
  5643     item->iData=aMenuItem;
       
  5644     TInt position = 0;
       
  5645     ItemAndPos( aPreviousId, position );
       
  5646     iItemArray->InsertL( position + 1, item);
       
  5647     UpdateScrollBar();
       
  5648     }
       
  5649 
       
  5650 
       
  5651 
       
  5652 // -----------------------------------------------------------------------------
       
  5653 // CEikMenuPane::DeleteMenuItem
       
  5654 // Deletes the menu item identified by aCommandId from the pane's item array.
       
  5655 //  Updates the menu's scroll bar to take acount of the change.
       
  5656 // -----------------------------------------------------------------------------
       
  5657 //
       
  5658 EXPORT_C void CEikMenuPane::DeleteMenuItem( TInt aCommandId )
       
  5659     {
       
  5660     TInt count=0;
       
  5661     if( iItemArray )
       
  5662         count=iItemArray->Count();
       
  5663     for ( TInt ii = 0; ii < count; ++ii )
       
  5664         {
       
  5665         CEikMenuPaneItem* item=(*iItemArray)[ii];
       
  5666         if ( item->iData.iCommandId == aCommandId )
       
  5667             {
       
  5668             iItemArray->Delete( ii );
       
  5669             delete item;
       
  5670             UpdateScrollBar();
       
  5671             return;
       
  5672             }
       
  5673         }
       
  5674     Panic( EEikPanicNoSuchMenuItem );
       
  5675     }
       
  5676 
       
  5677 // -----------------------------------------------------------------------------
       
  5678 // CEikMenuPane::DeleteBetweenMenuItems
       
  5679 // -----------------------------------------------------------------------------
       
  5680 //
       
  5681 EXPORT_C void CEikMenuPane::DeleteBetweenMenuItems( TInt aStartIndex, TInt aEndIndex )
       
  5682     {
       
  5683     __ASSERT_DEBUG( aStartIndex <= aEndIndex, Panic( EEikPanicNoSuchMenuItem ) );
       
  5684     TInt items(0);
       
  5685     if( iItemArray )
       
  5686         items=iItemArray->Count();
       
  5687     if ( aEndIndex >= items )
       
  5688         Panic( EEikPanicNoSuchMenuItem );
       
  5689 
       
  5690     TInt count = aEndIndex - aStartIndex + 1;
       
  5691     for ( TInt ii = 0; ii < count; ii++ )
       
  5692         {
       
  5693         CEikMenuPaneItem* item = (*iItemArray)[aStartIndex];
       
  5694         iItemArray->Delete( aStartIndex );
       
  5695         delete item;
       
  5696         }
       
  5697     UpdateScrollBar();
       
  5698     }
       
  5699 
       
  5700 
       
  5701 
       
  5702 // -----------------------------------------------------------------------------
       
  5703 // CEikMenuPane::ItemData
       
  5704 // Returns a reference to the data in the menu item identified by aCommandId.
       
  5705 // -----------------------------------------------------------------------------
       
  5706 //
       
  5707 EXPORT_C CEikMenuPaneItem::SData& CEikMenuPane::ItemData( TInt aCommandId )
       
  5708     {
       
  5709     TInt pos;
       
  5710     CEikMenuPaneItem* item=ItemAndPos( aCommandId, pos );
       
  5711     return item->iData;
       
  5712     }
       
  5713 
       
  5714 
       
  5715 // -----------------------------------------------------------------------------
       
  5716 // CEikMenuPane::ItemAndPos
       
  5717 // Returns a pointer to the menu item identified by aCommandId and gets the position of the item in aPos.
       
  5718 // -----------------------------------------------------------------------------
       
  5719 //
       
  5720 EXPORT_C CEikMenuPaneItem* CEikMenuPane::ItemAndPos( TInt aCommandId, TInt& aPos )
       
  5721     {
       
  5722     TInt count(0);
       
  5723     if( iItemArray )
       
  5724         count = iItemArray->Count();
       
  5725     aPos = 0;
       
  5726     CEikMenuPaneItem* item;
       
  5727     FOREVER
       
  5728         {
       
  5729         if ( aPos == count )
       
  5730             Panic( EEikPanicNoSuchMenuItem );
       
  5731         item = (*iItemArray)[aPos];
       
  5732         if ( item->iData.iCommandId == aCommandId )
       
  5733             break;
       
  5734         ++aPos;
       
  5735         }
       
  5736     return item;
       
  5737     }
       
  5738 
       
  5739 // -----------------------------------------------------------------------------
       
  5740 // CEikMenuPane::SetItemTextL
       
  5741 // Sets the text of the menu item identified by aCommandId by reading it from the resource with id aRid.
       
  5742 // -----------------------------------------------------------------------------
       
  5743 //
       
  5744 EXPORT_C void CEikMenuPane::SetItemTextL(TInt aCommandId,TInt aRid)
       
  5745     {
       
  5746     TBuf<80> tmp;
       
  5747     iCoeEnv->ReadResource( tmp, aRid );
       
  5748     SetItemTextL( aCommandId, tmp);
       
  5749     }
       
  5750 
       
  5751 
       
  5752 // -----------------------------------------------------------------------------
       
  5753 // CEikMenuPane::SetItemTextL
       
  5754 // Sets the text of the menu item identified by aCommandId to the descriptor aDes.
       
  5755 // -----------------------------------------------------------------------------
       
  5756 //
       
  5757 EXPORT_C void CEikMenuPane::SetItemTextL( TInt aCommandId, const TDesC& aDes )
       
  5758     {
       
  5759     TInt pos;
       
  5760     CEikMenuPaneItem* newItem=ItemAndPos( aCommandId, pos );
       
  5761     newItem->iData.iText.Copy( aDes );
       
  5762     }
       
  5763 
       
  5764 // -----------------------------------------------------------------------------
       
  5765 // CEikMenuPane::SetItemDimmed
       
  5766 // -----------------------------------------------------------------------------
       
  5767 //
       
  5768 EXPORT_C void CEikMenuPane::SetItemDimmed( TInt aCommandId, TBool aDimmed )
       
  5769     {
       
  5770     CEikMenuPaneItem::SData& itemData = ItemData(aCommandId);
       
  5771     if ( aDimmed )
       
  5772         itemData.iFlags |= EEikMenuItemDimmed;
       
  5773     else
       
  5774         itemData.iFlags &= ( ~EEikMenuItemDimmed );
       
  5775     }
       
  5776 
       
  5777 
       
  5778 // -----------------------------------------------------------------------------
       
  5779 // CEikMenuPane::SetItemButtonState
       
  5780 // Sets the item to be indicated or not. It should be used to change the state of radio
       
  5781 // buttons or check box items.
       
  5782 // It has real effect only starting from v3.0.
       
  5783 // @param aButtonState should be EEikMenuItemSymbolOn or EEikMenuItemSymbolIndeterminate
       
  5784 // -----------------------------------------------------------------------------
       
  5785 //
       
  5786 EXPORT_C void CEikMenuPane::SetItemButtonState( TInt aCommandId,TInt aButtonState )
       
  5787 {
       
  5788     TInt pos(0);
       
  5789     CEikMenuPaneItem* item = ItemAndPos( aCommandId, pos );
       
  5790 
       
  5791     if ( IsItemMemberOfRadioButtonGroup( pos ) )
       
  5792         {
       
  5793         if( aButtonState&EEikMenuItemSymbolOn )
       
  5794             {
       
  5795             iExtension->iSelectedRadioButtonItem = pos;
       
  5796             }
       
  5797         else if( iExtension->iSelectedRadioButtonItem == pos )
       
  5798             {
       
  5799             iExtension->iSelectedRadioButtonItem = KNoSelectedRadioButtonItem;
       
  5800             }
       
  5801         }
       
  5802 
       
  5803     item->iData.iFlags&=( ~(EEikMenuItemSymbolOn|EEikMenuItemSymbolIndeterminate) ); // clears the flags
       
  5804     if ( aButtonState&EEikMenuItemSymbolOn )
       
  5805         {
       
  5806         item->iData.iFlags |= EEikMenuItemSymbolOn;
       
  5807         }
       
  5808     else if ( aButtonState&EEikMenuItemSymbolIndeterminate )
       
  5809         {
       
  5810         item->iData.iFlags |= EEikMenuItemSymbolIndeterminate;
       
  5811         }
       
  5812     }
       
  5813 
       
  5814 // -----------------------------------------------------------------------------
       
  5815 // CEikMenuPane::SetSelectedItem
       
  5816 // -----------------------------------------------------------------------------
       
  5817 //
       
  5818 EXPORT_C void CEikMenuPane::SetSelectedItem( TInt aSelectedItem )
       
  5819     {
       
  5820     iSelectedItem = (aSelectedItem >= NumberOfItemsInPane() ) ? 0 : aSelectedItem;
       
  5821 
       
  5822     if( iExtension )
       
  5823         iExtension->ChangeHighlightBackground();
       
  5824     }
       
  5825 
       
  5826 // -----------------------------------------------------------------------------
       
  5827 // CEikMenuPane::SelectedItem
       
  5828 // -----------------------------------------------------------------------------
       
  5829 //
       
  5830 EXPORT_C TInt CEikMenuPane::SelectedItem() const
       
  5831     {
       
  5832     return iSelectedItem;
       
  5833     }
       
  5834 
       
  5835 // -----------------------------------------------------------------------------
       
  5836 // CEikMenuPane::SetItemArray
       
  5837 // -----------------------------------------------------------------------------
       
  5838 //
       
  5839 EXPORT_C void CEikMenuPane::SetItemArray( CItemArray* aItemArray )
       
  5840     {
       
  5841     if ( !ItemArrayOwnedExternally() )
       
  5842         delete iItemArray;
       
  5843     iItemArray = aItemArray;
       
  5844     }
       
  5845 
       
  5846 // -----------------------------------------------------------------------------
       
  5847 // CEikMenuPane::SetItemArrayOwnedExternally
       
  5848 // -----------------------------------------------------------------------------
       
  5849 //
       
  5850 EXPORT_C void CEikMenuPane::SetItemArrayOwnedExternally( TBool aOwnedExternally )
       
  5851     {
       
  5852     iArrayOwnedExternally=aOwnedExternally;
       
  5853     }
       
  5854 
       
  5855 // -----------------------------------------------------------------------------
       
  5856 // CEikMenuPane::SetLaunchingButton
       
  5857 // -----------------------------------------------------------------------------
       
  5858 //
       
  5859 EXPORT_C void CEikMenuPane::SetLaunchingButton( CEikButtonBase* aButton )
       
  5860     {
       
  5861     iLaunchingButton = aButton;
       
  5862     }
       
  5863 
       
  5864 
       
  5865 // -----------------------------------------------------------------------------
       
  5866 // CEikMenuPane::NumberOfItemsInPane
       
  5867 // Returns the number of menu items.
       
  5868 // -----------------------------------------------------------------------------
       
  5869 //
       
  5870 EXPORT_C TInt CEikMenuPane::NumberOfItemsInPane() const
       
  5871     {
       
  5872     return( iItemArray ? iItemArray->Count() : 0);
       
  5873     }
       
  5874 
       
  5875 // -----------------------------------------------------------------------------
       
  5876 //  CEikMenuPane::Close
       
  5877 // -----------------------------------------------------------------------------
       
  5878 //
       
  5879 EXPORT_C void CEikMenuPane::Close()
       
  5880     {
       
  5881     if( iExtension )
       
  5882         {
       
  5883         iExtension->iPressedDown = EFalse;
       
  5884         iExtension->ResetPressedHighlight();
       
  5885         }
       
  5886             
       
  5887     if ( OwnsWindow() )
       
  5888         CloseWindow();
       
  5889 
       
  5890     if( iExtension )
       
  5891         iExtension->MenuClosed();
       
  5892     }
       
  5893 
       
  5894 // -----------------------------------------------------------------------------
       
  5895 // CEikMenuPane::Reserved_1
       
  5896 // -----------------------------------------------------------------------------
       
  5897 //
       
  5898 EXPORT_C void CEikMenuPane::Reserved_1()
       
  5899     {}
       
  5900 
       
  5901 // -----------------------------------------------------------------------------
       
  5902 // CEikMenuPane::Reserved_2
       
  5903 // -----------------------------------------------------------------------------
       
  5904 //
       
  5905 EXPORT_C void CEikMenuPane::Reserved_2()
       
  5906     {}
       
  5907 
       
  5908 
       
  5909 //----------------------------------------------------------------------------
       
  5910 // CEikMenuPane::HandleScrollEventL()
       
  5911 //
       
  5912 // Handles scroll events by calculating new top and botton item indexes
       
  5913 // and then drawing all items that fit to screen
       
  5914 //----------------------------------------------------------------------------
       
  5915 //
       
  5916 void CEikMenuPane::HandleScrollEventL( CEikScrollBar* aScrollBar, TEikScrollEvent aEventType )
       
  5917     {
       
  5918     _AKNTRACE_FUNC_ENTER;
       
  5919     if( !AknLayoutUtils::PenEnabled())
       
  5920         {
       
  5921         return;
       
  5922         }
       
  5923 
       
  5924     _AKNTRACE( "[%s]", "Stop physics engine");
       
  5925     iExtension->iPhysics->StopPhysics();
       
  5926     iExtension->iPhysics->ResetFriction();
       
  5927 
       
  5928     // flag for do we need to update or even calculate scrolling
       
  5929     TBool update = ETrue;
       
  5930 
       
  5931     // if submenu is opened, close it because scrolling in submenu is not possible.
       
  5932     // and in this case it also means tapping outside of submenu.
       
  5933     if (iCascadeMenuPane)
       
  5934         {
       
  5935         _AKNTRACE( "[%s]", "CloseCascadeMenu");
       
  5936         CloseCascadeMenu();
       
  5937         update = EFalse;
       
  5938         }
       
  5939 
       
  5940     // how many items fit to view
       
  5941     const TInt itemsThatFitToView = NumberOfItemsThatFitInView();
       
  5942 
       
  5943     // How many items there are in this menu.
       
  5944     TInt countOfItems = 0;
       
  5945     if( iItemArray )
       
  5946         {
       
  5947         countOfItems = iItemArray->Count();
       
  5948         }
       
  5949 
       
  5950     // if scrolling is impossible because (there is not enough items to be scrolled)
       
  5951     if ( countOfItems < itemsThatFitToView )
       
  5952         {
       
  5953         update = EFalse;
       
  5954         }
       
  5955 
       
  5956     // Get top and botton item indexes.
       
  5957     TInt topItem = iScroller->TopItemIndex();
       
  5958     TInt bottomItem = topItem + itemsThatFitToView;
       
  5959     _AKNTRACE( "topItem = %d", topItem);
       
  5960     _AKNTRACE( "bottomItem = %d", bottomItem);
       
  5961 
       
  5962     if( bottomItem > NumberOfItemsInPane() )
       
  5963         {
       
  5964         bottomItem = NumberOfItemsInPane();
       
  5965         }
       
  5966 
       
  5967     // Items that becomes topmost and downmost items
       
  5968     TInt newTopItem = 0;
       
  5969 
       
  5970 
       
  5971     // if update is not wanted, do nothing.
       
  5972     if ( update )
       
  5973         {
       
  5974 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  5975         MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal(
       
  5976                 iExtension->iGc );
       
  5977         TBool effects = transApi && !transApi->EffectsDisabled();
       
  5978 #endif
       
  5979 
       
  5980         switch (aEventType)
       
  5981             {
       
  5982             case EEikScrollUp:
       
  5983                 {
       
  5984                 _AKNTRACE( "[%s]", "EEikScrollUp");
       
  5985                 _AKNTRACE( "topItem = %d", topItem);
       
  5986                 // if topItem is not upmost
       
  5987                 if ( topItem > 0)
       
  5988                     {
       
  5989                     // move menu to one step up.
       
  5990                     newTopItem = topItem - 1;
       
  5991                     }
       
  5992                 else
       
  5993                     {
       
  5994                     newTopItem = countOfItems - itemsThatFitToView;
       
  5995                     }
       
  5996                 _AKNTRACE( "newTopItem = %d", newTopItem);
       
  5997                 }
       
  5998                 break;
       
  5999 
       
  6000             case EEikScrollDown:
       
  6001                 {
       
  6002                 _AKNTRACE( "[%s]", "EEikScrollDown");
       
  6003                 _AKNTRACE( "bottomItem = %d", bottomItem);
       
  6004                 // if last item is not visible
       
  6005                 if ( bottomItem < countOfItems)
       
  6006                     {
       
  6007                     // move menu to show one step down.
       
  6008                     newTopItem = topItem + 1;
       
  6009                     }
       
  6010                 else
       
  6011                     {
       
  6012                     newTopItem = 0;
       
  6013                     }
       
  6014                 _AKNTRACE( "newTopItem = %d", newTopItem);
       
  6015                 }
       
  6016                 break;
       
  6017 
       
  6018             case EEikScrollPageUp:
       
  6019                 {
       
  6020                 _AKNTRACE( "[%s]", "EEikScrollPageUp");
       
  6021                 _AKNTRACE( "topItem = %d", topItem);
       
  6022                 // if topItem is not upmost
       
  6023                 if ( topItem > 0)
       
  6024                     {
       
  6025                     // move menu to show one site up or then upmost.
       
  6026                     newTopItem = (topItem > itemsThatFitToView) ? (topItem - itemsThatFitToView) : 0;
       
  6027                     }
       
  6028                 else
       
  6029                     {
       
  6030                     update = EFalse;
       
  6031                     }
       
  6032                 _AKNTRACE( "newTopItem = %d", newTopItem);
       
  6033                 _AKNTRACE( "update = %d", update);
       
  6034                 }
       
  6035                 break;
       
  6036 
       
  6037             case EEikScrollPageDown:
       
  6038                 {
       
  6039                 _AKNTRACE( "[%s]", "EEikScrollPageDown");
       
  6040                 _AKNTRACE( "bottomItem = %d", bottomItem);
       
  6041                 // if last item is not visible
       
  6042                 if ( bottomItem < countOfItems)
       
  6043                     {
       
  6044                     // move menu to show one site down or then downmost items.
       
  6045                     newTopItem = (bottomItem <=  (countOfItems - itemsThatFitToView)) ? (topItem + itemsThatFitToView) : (countOfItems - itemsThatFitToView);
       
  6046                     }
       
  6047                 else
       
  6048                     {
       
  6049                     update = EFalse;
       
  6050                     }
       
  6051                 _AKNTRACE( "newTopItem = %d", newTopItem);
       
  6052                 _AKNTRACE( "update = %d", update);
       
  6053                 }
       
  6054                 break;
       
  6055 
       
  6056             case EEikScrollThumbDragVert:
       
  6057                 {
       
  6058                 _AKNTRACE( "[%s]", "EEikScrollThumbDragVert");
       
  6059 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  6060 
       
  6061                 if ( effects )
       
  6062                     {
       
  6063                     MAknListBoxTfx* tfxApi = CAknListLoader::TfxApi( iExtension->iGc );
       
  6064                     
       
  6065                     if ( tfxApi )
       
  6066                         {
       
  6067                         tfxApi->EnableEffects( EFalse );
       
  6068                         effects = EFalse;
       
  6069                         }
       
  6070                     }
       
  6071 #endif
       
  6072                 // new thumb position
       
  6073                 TInt thumb = aScrollBar->ThumbPosition();
       
  6074                 _AKNTRACE( "thumb = %d", thumb);
       
  6075 
       
  6076                 // did dragging cause scrolling
       
  6077                 if ( thumb != topItem )
       
  6078                     {
       
  6079                     newTopItem = thumb;
       
  6080                     }
       
  6081                 else
       
  6082                     {
       
  6083                     update = EFalse;
       
  6084                     }
       
  6085                 _AKNTRACE( "newTopItem = %d", newTopItem);
       
  6086                 _AKNTRACE( "update = %d", update);
       
  6087                 }
       
  6088                 break;
       
  6089 
       
  6090             case EEikScrollThumbReleaseVert:
       
  6091                 {
       
  6092 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  6093                 MAknListBoxTfx* tfxApi = CAknListLoader::TfxApi( iExtension->iGc );
       
  6094                 
       
  6095                 if ( tfxApi )
       
  6096                     {
       
  6097                     tfxApi->EnableEffects( ETrue );
       
  6098                     }
       
  6099 #endif
       
  6100                 }
       
  6101                 return;
       
  6102                 
       
  6103             default:
       
  6104                 update = EFalse;
       
  6105                 break;
       
  6106             }
       
  6107 
       
  6108 
       
  6109 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  6110             if ( effects )
       
  6111                 {
       
  6112                 transApi->SetMoveType( newTopItem > topItem ?
       
  6113                     MAknListBoxTfxInternal::EListScrollDown :
       
  6114                     MAknListBoxTfxInternal::EListScrollUp );
       
  6115                 }
       
  6116 #endif
       
  6117 
       
  6118             
       
  6119             iExtension->iListTopIndex = aScrollBar->ThumbPosition();
       
  6120                            
       
  6121             iExtension->iViewPosition.iY = 
       
  6122                 iExtension->iListTopIndex + iExtension->iViewHeight / 2;              
       
  6123                           
       
  6124             iExtension->ViewPositionChanged( iExtension->iViewPosition );
       
  6125 
       
  6126         }
       
  6127     _AKNTRACE_FUNC_EXIT;
       
  6128     }
       
  6129 
       
  6130 // -----------------------------------------------------------------------------
       
  6131 // CEikMenuPane::CreateScrollBarFrame
       
  6132 // -----------------------------------------------------------------------------
       
  6133 //
       
  6134 void CEikMenuPane::CreateScrollBarFrame()
       
  6135     {
       
  6136     if (!CheckCreateScroller())
       
  6137         return;
       
  6138     TRAPD( err,( iSBFrame = new(ELeave) CEikScrollBarFrame( this, iScroller, ETrue, ETrue ) ) );
       
  6139     if ( !err )
       
  6140         {
       
  6141         CEikScrollBarFrame::TScrollBarVisibility visibility = CEikScrollBarFrame::EOn;
       
  6142 
       
  6143         if ( iOwner && ( iItemArray->Count() <= NumberOfItemsThatFitInView() ) )
       
  6144             {
       
  6145             // submenu with less than 6 items
       
  6146             visibility = CEikScrollBarFrame::EOff;
       
  6147             }
       
  6148         TRAP_IGNORE( iSBFrame->SetScrollBarVisibilityL( CEikScrollBarFrame::EOff, visibility /*CEikScrollBarFrame::EAuto*/ ) );
       
  6149 
       
  6150         TRAP_IGNORE( iSBFrame->CreateDoubleSpanScrollBarsL( EFalse, EFalse, ETrue, EFalse ) );
       
  6151         iSBFrame->DrawBackground( EFalse, EFalse );
       
  6152         UpdateScrollBar();
       
  6153         }
       
  6154     }
       
  6155 
       
  6156 
       
  6157 // -----------------------------------------------------------------------------
       
  6158 // CEikMenuPane::UpdateScrollBar
       
  6159 // -----------------------------------------------------------------------------
       
  6160 //
       
  6161 void CEikMenuPane::UpdateScrollBar()
       
  6162     {
       
  6163     if ( !CheckCreateScroller() )
       
  6164         return;
       
  6165     CIdle* idle = iScroller->Idle();
       
  6166     if ( idle && !idle->IsActive() )
       
  6167         idle->Start( TCallBack( CEikMenuPane::UpdateScrollBarCallBackL, this ) );
       
  6168     }
       
  6169 
       
  6170 // -----------------------------------------------------------------------------
       
  6171 // CEikMenuPane::UpdateScrollBarCallBackL
       
  6172 // -----------------------------------------------------------------------------
       
  6173 //
       
  6174 TInt CEikMenuPane::UpdateScrollBarCallBackL( TAny* aObj )
       
  6175     { // static
       
  6176     REINTERPRET_CAST(CEikMenuPane*,aObj)->DoUpdateScrollBarL();
       
  6177     return 0;
       
  6178     }
       
  6179 
       
  6180 // -----------------------------------------------------------------------------
       
  6181 // CEikMenuPane::DoUpdateScrollBarL
       
  6182 // -----------------------------------------------------------------------------
       
  6183 //
       
  6184 void CEikMenuPane::DoUpdateScrollBarL()
       
  6185     {
       
  6186     if (!iSBFrame)
       
  6187         return;
       
  6188     _AKNTRACE_FUNC_ENTER;
       
  6189     TEikScrollBarModel hSbarModel;
       
  6190     TEikScrollBarModel vSbarModel;
       
  6191 
       
  6192     TRect menuPaneRect;
       
  6193     if ( !iOwner )
       
  6194         {
       
  6195         menuPaneRect = iExtension->iMenuPaneRect;    
       
  6196         }
       
  6197     else
       
  6198         {
       
  6199         menuPaneRect = Rect();    
       
  6200         }
       
  6201     
       
  6202     TRect clientRect( menuPaneRect.Size() ); 
       
  6203 
       
  6204     // Panning uses pixel resolution scrollbar
       
  6205     vSbarModel.iThumbPosition = iExtension->iListTopIndex;      
       
  6206     vSbarModel.iScrollSpan = TotalItemHeight();
       
  6207     vSbarModel.iThumbSpan = iExtension->iViewHeight;
       
  6208 
       
  6209     // Double span scroll bar uses different model, just convert to it here.
       
  6210     TAknDoubleSpanScrollBarModel hDsSbarModel( hSbarModel );
       
  6211     TAknDoubleSpanScrollBarModel vDsSbarModel( vSbarModel );
       
  6212 
       
  6213     TRect scrollBarInclusiveRect( clientRect );
       
  6214     TRect scrollBarClientRect( scrollBarInclusiveRect );
       
  6215 
       
  6216     TEikScrollBarFrameLayout layout;
       
  6217     layout.SetClientMargin( 0 );
       
  6218     layout.SetInclusiveMargin( 0 );
       
  6219     layout.iTilingMode = TEikScrollBarFrameLayout::EClientRectConstant;
       
  6220 
       
  6221     // For main menupane scrollbar is always shown, for submenu only when needed
       
  6222     if ( !iOwner )
       
  6223         {
       
  6224         iSBFrame->SetScrollBarVisibilityL( CEikScrollBarFrame::EOff, CEikScrollBarFrame::EOn );
       
  6225         }
       
  6226     else
       
  6227         {
       
  6228         TInt maxItems = NumberOfItemsThatFitInView();
       
  6229         TInt count = iItemArray->Count();
       
  6230         iSBFrame->SetScrollBarVisibilityL( CEikScrollBarFrame::EOff,
       
  6231             (count > maxItems) ? CEikScrollBarFrame::EOn : CEikScrollBarFrame::EOff );
       
  6232         }
       
  6233 
       
  6234     TAknLayoutRect scrollLayoutRect;
       
  6235     if ( !iOwner )
       
  6236         {
       
  6237         TAknWindowLineLayout listScrollPaneLayout( 
       
  6238             AknLayoutScalable_Avkon::listscroll_menu_pane(0).LayoutLine() );
       
  6239         if ( iExtension )
       
  6240             {
       
  6241             iExtension->AdjustPopupLayoutData( listScrollPaneLayout );
       
  6242             }
       
  6243         scrollLayoutRect.LayoutRect( clientRect, listScrollPaneLayout );
       
  6244         scrollBarInclusiveRect =  scrollLayoutRect.Rect();
       
  6245         scrollBarClientRect = scrollBarInclusiveRect;
       
  6246 
       
  6247         AknLayoutUtils::LayoutVerticalScrollBar( iSBFrame, scrollBarClientRect,
       
  6248             AknLayoutScalable_Avkon::scroll_pane_cp25(0).LayoutLine() );
       
  6249         }
       
  6250     else
       
  6251         {
       
  6252         scrollLayoutRect.LayoutRect( clientRect, 
       
  6253                 AknLayoutScalable_Avkon::listscroll_popup_sub_pane().LayoutLine() );
       
  6254         scrollBarInclusiveRect = scrollLayoutRect.Rect();
       
  6255         scrollBarClientRect = scrollBarInclusiveRect;
       
  6256 
       
  6257         AknLayoutUtils::LayoutVerticalScrollBar( iSBFrame, scrollBarClientRect,
       
  6258           AknLayoutScalable_Avkon::scroll_pane_cp4().LayoutLine());
       
  6259         }
       
  6260 
       
  6261     iSBFrame->TileL( &hDsSbarModel, &vDsSbarModel, scrollBarClientRect, scrollBarInclusiveRect, layout );
       
  6262     iSBFrame->SetVFocusPosToThumbPos( vDsSbarModel.FocusPosition() );
       
  6263     
       
  6264 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  6265     MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( iExtension->iGc );
       
  6266     if ( iSBFrame->VerticalScrollBar() &&
       
  6267          iSBFrame->VScrollBarVisibility() == CEikScrollBarFrame::EOn )
       
  6268         {
       
  6269         iExtension->iScrollBarRect = iSBFrame->VerticalScrollBar()->Rect();
       
  6270         }
       
  6271     else
       
  6272         {
       
  6273         iExtension->iScrollBarRect = TRect::EUninitialized;
       
  6274         }
       
  6275     if ( transApi )
       
  6276         {
       
  6277         transApi->ResetNonDrawingRects();
       
  6278         transApi->AddNonDrawingRect( iExtension->iScrollBarRect );
       
  6279         transApi->AddNonDrawingRect( iExtension->iSctRect );
       
  6280         }
       
  6281 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  6282     if ( iSBFrame->VerticalScrollBar() &&
       
  6283          iSBFrame->VScrollBarVisibility() == CEikScrollBarFrame::EOn )
       
  6284         {
       
  6285         iExtension->iSBRect = iSBFrame->VerticalScrollBar()->Rect();       
       
  6286         }
       
  6287     else
       
  6288         {
       
  6289         iExtension->iSBRect = TRect::EUninitialized;
       
  6290         }        
       
  6291     _AKNTRACE_FUNC_EXIT;
       
  6292     }
       
  6293 
       
  6294 // -----------------------------------------------------------------------------
       
  6295 // CEikMenuPane::UpdateScrollBarThumbs
       
  6296 // -----------------------------------------------------------------------------
       
  6297 //
       
  6298 void CEikMenuPane::UpdateScrollBarThumbs()
       
  6299     {
       
  6300     if ( iSBFrame )
       
  6301         {
       
  6302         iSBFrame->SetVFocusPosToThumbPos( iExtension->iListTopIndex );             
       
  6303         }
       
  6304     }
       
  6305 
       
  6306 // -----------------------------------------------------------------------------
       
  6307 // CEikMenuPane::ScrollToMakeItemVisible
       
  6308 // -----------------------------------------------------------------------------
       
  6309 //
       
  6310 void CEikMenuPane::ScrollToMakeItemVisible(TInt aItemIndex)
       
  6311     {
       
  6312     _AKNTRACE_FUNC_ENTER;
       
  6313     if( !iItemArray || iItemArray->Count() == 0 )
       
  6314         return;
       
  6315     if ( !CheckCreateScroller() )
       
  6316         return;
       
  6317 
       
  6318     if(iExtension->iSctHighlighted && aItemIndex == ENothingSelected)
       
  6319         aItemIndex = 0;
       
  6320     else if(aItemIndex == ENothingSelected)
       
  6321         return;
       
  6322 
       
  6323     TInt maxItems = NumberOfItemsThatFitInView();
       
  6324     
       
  6325     if ( iExtension->Offset() < 0 )
       
  6326         {
       
  6327         maxItems++;
       
  6328         }
       
  6329     //
       
  6330     // S60 menus are fixed size pitch and known size so scrolling can be based on index
       
  6331     //
       
  6332     TInt amountToScroll = 0;
       
  6333     if ( aItemIndex < iScroller->TopItemIndex() )
       
  6334         { // +ve scroll
       
  6335         amountToScroll = iItemHeight * ( iScroller->TopItemIndex() - aItemIndex );
       
  6336         }
       
  6337     else if ( aItemIndex >= ( iScroller->TopItemIndex() + maxItems ) )
       
  6338         {
       
  6339         amountToScroll = iItemHeight * (  ( iScroller->TopItemIndex() +
       
  6340             maxItems ) - aItemIndex - 1 );
       
  6341         }
       
  6342     if ( amountToScroll )
       
  6343         {
       
  6344         _AKNTRACE( "amountToScroll =  %d", amountToScroll );
       
  6345         Scroll(amountToScroll);
       
  6346         
       
  6347         if ( !iExtension->isUpdateScrollDirectly )
       
  6348             {
       
  6349             UpdateScrollBar();
       
  6350             }
       
  6351         else
       
  6352             {
       
  6353             DoUpdateScrollBarL();
       
  6354             }        
       
  6355         }
       
  6356     _AKNTRACE_FUNC_EXIT;
       
  6357     return;
       
  6358     }
       
  6359 
       
  6360 // -----------------------------------------------------------------------------
       
  6361 // CEikMenuPane::Scroll
       
  6362 // -----------------------------------------------------------------------------
       
  6363 //
       
  6364 void CEikMenuPane::Scroll( TInt aAmount )
       
  6365     {
       
  6366     _AKNTRACE_FUNC_ENTER;
       
  6367     if ( !CheckCreateScroller() )
       
  6368         return;
       
  6369     TInt count=0;
       
  6370     if( iItemArray )
       
  6371         count = iItemArray->Count();
       
  6372 
       
  6373     // convert aAmount to a multiple of iItemHeight.
       
  6374     TInt integer = aAmount / iItemHeight;
       
  6375     TReal real = TReal( TReal( aAmount ) / TReal( iItemHeight ) );
       
  6376     if ( real > TReal( integer ) ) // make more positive
       
  6377         aAmount = ( integer + 1 ) * iItemHeight;
       
  6378     if ( real < TReal( integer ) ) // make more negative
       
  6379         aAmount = ( integer - 1 ) * iItemHeight;
       
  6380 
       
  6381     // convert amount back into indices for S60
       
  6382     TInt newTop = iScroller->TopItemIndex() - ( aAmount / iItemHeight );  // don't think there should be a divide by 0 here.
       
  6383     newTop = Max( 0, newTop );
       
  6384     newTop = Min( newTop, count - NumberOfItemsThatFitInView() );
       
  6385     iScroller->SetTopItemIndex( newTop );
       
  6386     _AKNTRACE( "newTop =  %d", newTop );
       
  6387  
       
  6388     // Menu moved with keys, update panning/flicking data
       
  6389     iExtension->iListTopIndex = iScroller->TopItemIndex() * iItemHeight;
       
  6390     iExtension->iViewPosition.iY = 
       
  6391         iExtension->iListTopIndex + iExtension->iViewHeight / 2;  
       
  6392 
       
  6393     iExtension->SetOffset( 0 );
       
  6394 
       
  6395     _AKNTRACE( "iExtension->iListTopIndex =  %d", iExtension->iListTopIndex );
       
  6396     _AKNTRACE( "iExtension->iViewPosition.iY =  %d", iExtension->iViewPosition.iY );
       
  6397     _AKNTRACE( "[%s]", "iExtension->SetOffset( 0 )" );
       
  6398 
       
  6399     _AKNTRACE_FUNC_EXIT;
       
  6400     return;
       
  6401     }
       
  6402 
       
  6403 // -----------------------------------------------------------------------------
       
  6404 // CEikMenuPane::ViewRect
       
  6405 // -----------------------------------------------------------------------------
       
  6406 //
       
  6407 TRect CEikMenuPane::ViewRect() const
       
  6408     {
       
  6409     return Rect();
       
  6410     }
       
  6411 
       
  6412 // -----------------------------------------------------------------------------
       
  6413 // CEikMenuPane::NumberOfItemsThatFitInView
       
  6414 // -----------------------------------------------------------------------------
       
  6415 //
       
  6416 TInt CEikMenuPane::NumberOfItemsThatFitInView() const
       
  6417     {
       
  6418     TInt subst = 0;
       
  6419     if ( iExtension->iSct )
       
  6420         {
       
  6421         subst = 1;
       
  6422         }
       
  6423 #ifdef RD_UI_TRANSITION_EFFECTS_LIST        
       
  6424     iExtension->iItemsThatFitInView = iOwner ? AknLayoutScalable_Avkon::
       
  6425         list_single_popup_submenu_pane_ParamLimits().LastRow() + 1 :
       
  6426         AknLayoutScalable_Avkon::
       
  6427         list_single_pane_cp2_ParamLimits().LastRow() + 1 - subst;
       
  6428         if ( Layout_Meta_Data::IsLandscapeOrientation() 
       
  6429              && iExtension->iItemsThatFitInView == 6 )
       
  6430             {
       
  6431             iExtension->iItemsThatFitInView --;
       
  6432             }
       
  6433         
       
  6434     if ( iExtension->iPhysics && iExtension->Offset() != 0 )
       
  6435         {
       
  6436         // with kinetic scrolling there can be partial items on the screen 
       
  6437         iExtension->iTotalNumberOfItemsInView = iExtension->iItemsThatFitInView + 1;
       
  6438         }
       
  6439         
       
  6440     return iExtension->iItemsThatFitInView;
       
  6441 #else
       
  6442     return iOwner ? AknLayoutScalable_Avkon::
       
  6443         list_single_popup_submenu_pane_ParamLimits().LastRow() + 1 :
       
  6444         AknLayoutScalable_Avkon::
       
  6445         list_single_pane_cp2_ParamLimits().LastRow() + 1 - subst;
       
  6446 #endif
       
  6447     }
       
  6448 
       
  6449 // -----------------------------------------------------------------------------
       
  6450 // CEikMenuPane::TotalItemHeight
       
  6451 // -----------------------------------------------------------------------------
       
  6452 //
       
  6453 TInt CEikMenuPane::TotalItemHeight() const
       
  6454     {
       
  6455     TInt height(0);
       
  6456     TInt count(0);
       
  6457     if( iItemArray )
       
  6458         count = iItemArray->Count();
       
  6459     for (TInt ii = 0; ii < count; ++ii )
       
  6460         {
       
  6461         height += iItemHeight;
       
  6462         }
       
  6463 
       
  6464     if ( iExtension->iSct )
       
  6465         {
       
  6466         height += iItemHeight;
       
  6467         }
       
  6468     return height;
       
  6469     }
       
  6470 
       
  6471 
       
  6472 // -----------------------------------------------------------------------------
       
  6473 // CEikMenuPane::CheckCreateScroller
       
  6474 // -----------------------------------------------------------------------------
       
  6475 //
       
  6476 TBool CEikMenuPane::CheckCreateScroller()
       
  6477     {
       
  6478     TInt err = KErrNone;
       
  6479     if ( !iScroller )
       
  6480         {
       
  6481         TRAP( err,( iScroller = CMenuScroller::NewL( *this ) ) );
       
  6482         }
       
  6483     return err == KErrNone;
       
  6484     }
       
  6485 
       
  6486 // -----------------------------------------------------------------------------
       
  6487 // CEikMenuPane::CheckCreateScrollerL
       
  6488 // -----------------------------------------------------------------------------
       
  6489 //
       
  6490 void CEikMenuPane::CheckCreateScrollerL()
       
  6491     {
       
  6492     if ( !iScroller )
       
  6493         iScroller = CMenuScroller::NewL( *this );
       
  6494     }
       
  6495 
       
  6496 
       
  6497 // -----------------------------------------------------------------------------
       
  6498 // CEikMenuPane::ItemArrayOwnedExternally
       
  6499 // -----------------------------------------------------------------------------
       
  6500 //
       
  6501 TBool CEikMenuPane::ItemArrayOwnedExternally() const
       
  6502     {
       
  6503     return iArrayOwnedExternally;
       
  6504     }
       
  6505 
       
  6506 
       
  6507 // -----------------------------------------------------------------------------
       
  6508 // CEikMenuPane::GetColorUseListL
       
  6509 // Gets the list of logical colors employed in the drawing of the control,
       
  6510 // paired with an explanation of how they are used. Appends the list into aColorUseList.
       
  6511 //
       
  6512 // @since ER5U
       
  6513 // -----------------------------------------------------------------------------
       
  6514 //
       
  6515 EXPORT_C void CEikMenuPane::GetColorUseListL( CArrayFix<TCoeColorUse>& aColorUseList ) const
       
  6516     {
       
  6517     CEikBorderedControl::GetColorUseListL( aColorUseList );
       
  6518 
       
  6519     TInt commonAttributes = TCoeColorUse::ENormal|TCoeColorUse::ENeutral;
       
  6520     TCoeColorUse colorUse;
       
  6521 
       
  6522     colorUse.SetLogicalColor( EColorMenuPaneText );
       
  6523     colorUse.SetUse( TCoeColorUse::EFore|TCoeColorUse::EActive|TCoeColorUse::ESurrounds|commonAttributes );
       
  6524     aColorUseList.AppendL( colorUse );
       
  6525 
       
  6526     colorUse.SetLogicalColor( EColorMenuPaneBackground );
       
  6527     colorUse.SetUse( TCoeColorUse::EBack|TCoeColorUse::EActive|TCoeColorUse::ESurrounds|commonAttributes);
       
  6528     aColorUseList.AppendL( colorUse );
       
  6529 
       
  6530     colorUse.SetLogicalColor( EColorMenuPaneTextHighlight );
       
  6531     colorUse.SetUse( TCoeColorUse::EFore|TCoeColorUse::EActive|TCoeColorUse::EHighlights|commonAttributes );
       
  6532     aColorUseList.AppendL(colorUse);
       
  6533 
       
  6534     colorUse.SetLogicalColor( EColorMenuPaneHighlight );
       
  6535     colorUse.SetUse(TCoeColorUse::EBack|TCoeColorUse::EActive|TCoeColorUse::EHighlights|commonAttributes );
       
  6536     aColorUseList.AppendL( colorUse );
       
  6537 
       
  6538     colorUse.SetLogicalColor( EColorMenuPaneDimmedTextHighlight );
       
  6539     colorUse.SetUse( TCoeColorUse::EBack|TCoeColorUse::EDimmed|TCoeColorUse::EHighlights|commonAttributes );
       
  6540     aColorUseList.AppendL( colorUse );
       
  6541 
       
  6542     colorUse.SetLogicalColor( EColorMenuPaneDimmedHighlight );
       
  6543     colorUse.SetUse( TCoeColorUse::EFore|TCoeColorUse::EDimmed|TCoeColorUse::EHighlights|commonAttributes );
       
  6544     aColorUseList.AppendL( colorUse );
       
  6545 
       
  6546     colorUse.SetLogicalColor( EColorMenuPaneDimmedText );
       
  6547     colorUse.SetUse( TCoeColorUse::EBack|TCoeColorUse::EDimmed|TCoeColorUse::ESurrounds|commonAttributes);
       
  6548     aColorUseList.AppendL( colorUse );
       
  6549     }
       
  6550 
       
  6551 
       
  6552 // -----------------------------------------------------------------------------
       
  6553 // CEikMenuPane::HandleResourceChange
       
  6554 // Handles a change to the control's resources of type aType
       
  6555 // which are shared across the environment, e.g. colors or fonts.
       
  6556 //
       
  6557 // @since ER5U
       
  6558 // -----------------------------------------------------------------------------
       
  6559 //
       
  6560 EXPORT_C void CEikMenuPane::HandleResourceChange( TInt aType )
       
  6561     {
       
  6562     _AKNTRACE_FUNC_ENTER;
       
  6563     _AKNTRACE( "aType= %d",  aType );
       
  6564     if ( aType == KEikDynamicLayoutVariantSwitch )
       
  6565         {
       
  6566         if ( IsActivated() )
       
  6567             {
       
  6568             TInt maxItems = NumberOfItemsThatFitInView();
       
  6569             TInt topIndex = iScroller->TopItemIndex();            
       
  6570             TInt count = iItemArray->Count();
       
  6571             if ( count <= maxItems )
       
  6572                 {
       
  6573                 iScroller->SetTopItemIndex( 0 );
       
  6574                 topIndex = iScroller->TopItemIndex();
       
  6575                 }
       
  6576             //In portrait mode.   
       
  6577             if ( !Layout_Meta_Data::IsLandscapeOrientation() ) 
       
  6578                 {
       
  6579                 if( ( count > maxItems ) && ( count - topIndex < maxItems ) )
       
  6580                     {
       
  6581                     TInt maxItemGaps = maxItems - (count - topIndex);                
       
  6582                     iScroller->SetTopItemIndex( topIndex - maxItemGaps );
       
  6583                     topIndex = iScroller->TopItemIndex();
       
  6584                     }                 
       
  6585                 }
       
  6586             TInt index = iSelectedItem - topIndex;
       
  6587             if ( index >= maxItems )
       
  6588                 {
       
  6589                 topIndex = topIndex + (index + 1 - maxItems);
       
  6590                 iScroller->SetTopItemIndex( topIndex );              
       
  6591                 }
       
  6592             
       
  6593             TRect rect( CalculateSizeAndPosition() );
       
  6594             SetExtent( rect.iTl, rect.Size() );
       
  6595 
       
  6596             TRAP_IGNORE( DoUpdateScrollBarL() );
       
  6597 
       
  6598             UpdateBackgroundContext( Rect() );
       
  6599             PrepareHighlightFrame();
       
  6600             SetCascadedIconSize();
       
  6601 
       
  6602             // Background under highlight may have changed -> we need to update
       
  6603             // highlight background to animation
       
  6604             if( iExtension )
       
  6605                 {
       
  6606                 iExtension->HandleLayoutSwitch();
       
  6607                 }
       
  6608                           
       
  6609 #ifdef RD_UI_TRANSITION_EFFECTS_LIST        
       
  6610             MAknListBoxTfxInternal *transApi = CAknListLoader::TfxApiInternal( iExtension->iGc );
       
  6611             if ( transApi )
       
  6612                 {
       
  6613                 transApi->Remove( MAknListBoxTfxInternal:: EListEverything );
       
  6614                 }
       
  6615 #endif    
       
  6616             
       
  6617             //Initialize physics engine
       
  6618             if ( iExtension->iPhysics )
       
  6619                 {
       
  6620                 TRAP_IGNORE ( iExtension->InitPhysicsL() );
       
  6621                 iExtension->iListTopIndex = iScroller->TopItemIndex() * iItemHeight;
       
  6622                 iExtension->iViewPosition.iY = 
       
  6623                             iExtension->iListTopIndex + iExtension->iViewHeight / 2;  
       
  6624                 iExtension->ViewPositionChanged( iExtension->iViewPosition );
       
  6625                 } 
       
  6626             
       
  6627             if ( iCascadeMenuPane )
       
  6628                 {
       
  6629                 iCascadeMenuPane->HandleResourceChange( aType );
       
  6630                 } 
       
  6631             
       
  6632             }                                           
       
  6633         }
       
  6634     else if( aType == KEikMessageUnfadeWindows 
       
  6635              || aType == KEikMessageWindowsFadeChange 
       
  6636              || aType == KEikMessageFadeAllWindows )
       
  6637         {
       
  6638         //Fix for ELYG-7DR5UF
       
  6639         if ( IsActivated() )
       
  6640             {
       
  6641             CEikScrollBar *verScrollBar = iSBFrame->VerticalScrollBar();
       
  6642             if ( verScrollBar != NULL 
       
  6643                 && iSBFrame->VScrollBarVisibility() == CEikScrollBarFrame::EOn )
       
  6644                 {
       
  6645                 //iLastPointerEvent:Menu pane save the last pointer event in this
       
  6646                 // variable every time in HandlePointerEvent().
       
  6647                 if ( verScrollBar->Rect().Contains( iExtension->iLastPointerEvent.iPosition ) &&
       
  6648                     ( iExtension->iLastPointerEvent.iType == TPointerEvent::EButton1Down
       
  6649                     || iExtension->iLastPointerEvent.iType == TPointerEvent::EDrag ) )
       
  6650                     {
       
  6651                     TPointerEvent pointerEvent = iExtension->iLastPointerEvent;                    
       
  6652                     pointerEvent.iType = TPointerEvent::EButton1Up;
       
  6653                     // Sending a up event to scroll bar for dehighlighting 
       
  6654                     // the scroll bar.
       
  6655                     verScrollBar->HandlePointerEventL(pointerEvent);   
       
  6656                     iSBFrame->DrawScrollBarsDeferred();
       
  6657                     ClaimPointerGrab( EFalse );
       
  6658                     }
       
  6659                 }
       
  6660             // Fixed for TSW error ELLI-7UG89S
       
  6661             if ( iExtension && iExtension->iPressedDown )
       
  6662                 {                                
       
  6663                 iExtension->iPressedDown = EFalse;
       
  6664                 DrawNow();
       
  6665                 }
       
  6666             if ( iCascadeMenuPane )
       
  6667                 {
       
  6668                 iCascadeMenuPane->HandleResourceChange( aType );
       
  6669                 }
       
  6670             }
       
  6671         }
       
  6672     else if ( aType == KAknMessageFocusLost )
       
  6673         {
       
  6674         if ( iExtension && iExtension->HighlightEnabled() )
       
  6675             {
       
  6676             iExtension->EnableHighlight( EFalse, EFalse );
       
  6677             DrawItem( iSelectedItem, ENoHighlight );
       
  6678             }
       
  6679         }
       
  6680     else
       
  6681         {        
       
  6682         CCoeControl::HandleResourceChange( aType );
       
  6683         if ( aType == KAknsMessageSkinChange )
       
  6684             {
       
  6685             // fixed for TSW error ECGO-7NZCPR.
       
  6686             SetCascadedIconSize();
       
  6687             DrawDeferred();
       
  6688             }
       
  6689         }
       
  6690 
       
  6691     // Note: Animation is skin dependent, but it exists only when the menu is
       
  6692     // displayed (additionally, inactive menupane simply won't receive skin
       
  6693     // change event).
       
  6694     _AKNTRACE_FUNC_EXIT;
       
  6695     }
       
  6696 
       
  6697 
       
  6698 // -----------------------------------------------------------------------------
       
  6699 // CEikMenuPane::InsertMenuItemL
       
  6700 // -----------------------------------------------------------------------------
       
  6701 //
       
  6702 EXPORT_C void CEikMenuPane::InsertMenuItemL(const CEikMenuPaneItem::SData& aMenuItem, TInt aPosition)
       
  6703     {
       
  6704     if ( !iItemArray )
       
  6705         CreateItemArrayL();
       
  6706     CEikMenuPaneItem* item = new(ELeave) CEikMenuPaneItem();
       
  6707     item->iData = aMenuItem;
       
  6708     iItemArray->InsertL( aPosition, item );
       
  6709     UpdateScrollBar();
       
  6710     }
       
  6711 
       
  6712 // -----------------------------------------------------------------------------
       
  6713 // CEikMenuPane::MenuItemExists
       
  6714 // -----------------------------------------------------------------------------
       
  6715 //
       
  6716 EXPORT_C TBool CEikMenuPane::MenuItemExists( TInt aCommandId, TInt& aPosition )
       
  6717     {
       
  6718     TInt count(0);
       
  6719     if( iItemArray )
       
  6720         count = iItemArray->Count();
       
  6721     aPosition = 0;
       
  6722     CEikMenuPaneItem* item;
       
  6723     FOREVER
       
  6724         {
       
  6725         if ( aPosition == count )
       
  6726             return EFalse;
       
  6727         item  =(*iItemArray)[aPosition];
       
  6728         if ( item->iData.iCommandId == aCommandId )
       
  6729             break;
       
  6730         ++aPosition;
       
  6731         }
       
  6732     return ETrue;
       
  6733     }
       
  6734 
       
  6735 // -----------------------------------------------------------------------------
       
  6736 // CEikMenuPane::IsCascadeMenuPane
       
  6737 // -----------------------------------------------------------------------------
       
  6738 //
       
  6739 EXPORT_C TBool CEikMenuPane::IsCascadeMenuPane() const
       
  6740     {
       
  6741     return iOwner != NULL;
       
  6742     }
       
  6743 
       
  6744 // -----------------------------------------------------------------------------
       
  6745 // CEikMenuPane::CascadeMenuPane
       
  6746 // -----------------------------------------------------------------------------
       
  6747 //
       
  6748 EXPORT_C CEikMenuPane* CEikMenuPane::CascadeMenuPane()
       
  6749     {
       
  6750     return iCascadeMenuPane;
       
  6751     }
       
  6752 
       
  6753 // -----------------------------------------------------------------------------
       
  6754 // CEikMenuPane::ItemDataByIndexL
       
  6755 // Gets a reference to the data in the specified menu item.
       
  6756 // -----------------------------------------------------------------------------
       
  6757 //
       
  6758 EXPORT_C CEikMenuPaneItem::SData& CEikMenuPane::ItemDataByIndexL(TInt aItemIndex)
       
  6759     {
       
  6760     __ASSERT_ALWAYS( iItemArray, Panic( EEikPanicInvalidIndex ) );
       
  6761     if ( aItemIndex < 0 || aItemIndex >= iItemArray->Count() )
       
  6762         {
       
  6763         User::Leave( KErrArgument );
       
  6764         }
       
  6765 
       
  6766     CEikMenuPaneItem* item = (*iItemArray)[aItemIndex];
       
  6767     return item->iData;
       
  6768     }
       
  6769 
       
  6770 
       
  6771 // -----------------------------------------------------------------------------
       
  6772 // CEikMenuPane::LoadCascadeBitmapL
       
  6773 // -----------------------------------------------------------------------------
       
  6774 //
       
  6775 void CEikMenuPane::LoadCascadeBitmapL()
       
  6776     {
       
  6777     if ( iExtension )
       
  6778         {
       
  6779         if ( iExtension->iCascadeBitmap )
       
  6780             {
       
  6781             delete iExtension->iCascadeBitmap;
       
  6782             iExtension->iCascadeBitmap = NULL;
       
  6783             }
       
  6784         if ( iExtension->iCascadeBitmapMask )
       
  6785             {
       
  6786             delete iExtension->iCascadeBitmapMask;
       
  6787             iExtension->iCascadeBitmapMask = NULL;
       
  6788             }
       
  6789 
       
  6790         MAknsSkinInstance* skin = AknsUtils::SkinInstance();
       
  6791 
       
  6792         AknsUtils::CreateIconL( skin, KAknsIIDQgnIndiSubmenu, iExtension->iCascadeBitmap,
       
  6793             iExtension->iCascadeBitmapMask, KAvkonBitmapFile,
       
  6794             EMbmAvkonQgn_indi_submenu, EMbmAvkonQgn_indi_submenu_mask );
       
  6795 
       
  6796         }
       
  6797     }
       
  6798 
       
  6799 
       
  6800 // -----------------------------------------------------------------------------
       
  6801 // CEikMenuPane::LoadCheckMarkBitmapL
       
  6802 // Creates the bitmap and the mask for check mark icon
       
  6803 // -----------------------------------------------------------------------------
       
  6804 //
       
  6805 void CEikMenuPane::LoadCheckMarkBitmapL()
       
  6806     {
       
  6807     if ( iExtension )
       
  6808         {
       
  6809         if ( iExtension->iCheckMarkBitmap )
       
  6810             {
       
  6811             delete iExtension->iCheckMarkBitmap;
       
  6812             iExtension->iCheckMarkBitmap = NULL;
       
  6813             }
       
  6814         if ( iExtension->iCheckMarkBitmapMask )
       
  6815             {
       
  6816             delete iExtension->iCheckMarkBitmapMask;
       
  6817             iExtension->iCheckMarkBitmapMask = NULL;
       
  6818             }
       
  6819 
       
  6820         MAknsSkinInstance* skin = AknsUtils::SkinInstance();
       
  6821 
       
  6822         AknsUtils::CreateIconL( skin, KAknsIIDQgnPropSubMarked, iExtension->iCheckMarkBitmap,
       
  6823             iExtension->iCheckMarkBitmapMask, KAvkonBitmapFile,
       
  6824             EMbmAvkonQgn_prop_sub_marked, EMbmAvkonQgn_prop_sub_marked_mask );
       
  6825 
       
  6826         }
       
  6827     }
       
  6828 
       
  6829 
       
  6830 // -----------------------------------------------------------------------------
       
  6831 // CEikMenuPane::MenuHasCheckBoxOn
       
  6832 // @return ETrue if at least one of the items has a check box to be on
       
  6833 // -----------------------------------------------------------------------------
       
  6834 //
       
  6835 TBool CEikMenuPane::MenuHasCheckBoxOn() const
       
  6836     {
       
  6837     for (TInt i = 0; i < iItemArray->Count(); i++)
       
  6838         {
       
  6839         CEikMenuPaneItem* item=(*iItemArray)[i];
       
  6840         if ( item->iData.iFlags&EEikMenuItemCheckBox && item->iData.iFlags&EEikMenuItemSymbolOn )
       
  6841             return ETrue;
       
  6842         }
       
  6843     return EFalse;
       
  6844     }
       
  6845 
       
  6846 // -----------------------------------------------------------------------------
       
  6847 // CEikMenuPane::LoadRadioButtonBitmapL
       
  6848 // Loads the bitmap and the mask for radio button icon
       
  6849 // -----------------------------------------------------------------------------
       
  6850 //
       
  6851 void CEikMenuPane::LoadRadioButtonBitmapL()
       
  6852     {
       
  6853     if ( iExtension )
       
  6854         {
       
  6855         if ( iExtension->iRadioButtonBitmap )
       
  6856             {
       
  6857             delete iExtension->iRadioButtonBitmap;
       
  6858             iExtension->iRadioButtonBitmap = NULL;
       
  6859             }
       
  6860     if ( iExtension->iRadioButtonBitmapMask )
       
  6861         {
       
  6862         delete iExtension->iRadioButtonBitmapMask;
       
  6863         iExtension->iRadioButtonBitmapMask = NULL;
       
  6864         }
       
  6865 
       
  6866         MAknsSkinInstance* skin = AknsUtils::SkinInstance();
       
  6867 
       
  6868         AknsUtils::CreateIconL( skin, KAknsIIDQgnPropSubCurrent, iExtension->iRadioButtonBitmap,
       
  6869             iExtension->iRadioButtonBitmapMask, KAvkonBitmapFile,
       
  6870             EMbmAvkonQgn_prop_sub_current, EMbmAvkonQgn_prop_sub_current_mask );
       
  6871 
       
  6872         }
       
  6873 }
       
  6874 
       
  6875 
       
  6876 // -----------------------------------------------------------------------------
       
  6877 // CEikMenuPane::IsItemMemberOfRadioButtonGroup
       
  6878 // @return ETrue if the item in submenu is the member of the radio button group
       
  6879 // -----------------------------------------------------------------------------
       
  6880 //
       
  6881 TBool CEikMenuPane::IsItemMemberOfRadioButtonGroup(TInt aItem) const
       
  6882     {
       
  6883     if ( !( Extension()->iHasRadioGroup ) )
       
  6884         {
       
  6885         return EFalse;
       
  6886         }
       
  6887 
       
  6888     if (aItem < 0 || aItem >= iItemArray->Count())
       
  6889         {
       
  6890         return EFalse;
       
  6891         }
       
  6892 
       
  6893     CEikMenuPaneItem* item = (*iItemArray)[aItem];
       
  6894 
       
  6895     if ( item->iData.iFlags&( EEikMenuItemRadioStart|EEikMenuItemRadioMiddle|EEikMenuItemRadioEnd ) )
       
  6896         {
       
  6897         return ETrue;
       
  6898         }
       
  6899 
       
  6900     for ( TInt i = aItem; i >= 0; i-- )
       
  6901         {
       
  6902         // try to find the beginning of radio button group, otherwise this item is before radio button group
       
  6903         CEikMenuPaneItem* previuosItem = (*iItemArray)[i];
       
  6904         if (previuosItem->iData.iFlags&EEikMenuItemRadioStart)
       
  6905             {
       
  6906             return ETrue;
       
  6907             }
       
  6908         }
       
  6909     return EFalse;
       
  6910     }
       
  6911 
       
  6912 
       
  6913 // -----------------------------------------------------------------------------
       
  6914 // CEikMenuPane::MenuHasIcon
       
  6915 // @return ETrue if at least one of the menu items has some icon to be drawn before the text.
       
  6916 // It is needed for DrawItem() function to move the text of all items right or left depending on the layout.
       
  6917 // If the menu doesn't contain any icons then text is positioned as in normal situation.
       
  6918 // -----------------------------------------------------------------------------
       
  6919 //
       
  6920 TBool CEikMenuPane::MenuHasIcon() const
       
  6921     {
       
  6922     TBool retValue = EFalse;
       
  6923     // only submenus might contain radio button or check box
       
  6924     if ( iOwner && iExtension )
       
  6925         {
       
  6926         retValue = ( (iExtension->iHasRadioGroup) || MenuHasCheckBoxOn() );
       
  6927         }
       
  6928     return retValue;
       
  6929     }
       
  6930 
       
  6931 
       
  6932 // -----------------------------------------------------------------------------
       
  6933 // CEikMenuPane::CalculateSizeAndPositionScalable
       
  6934 // Calculate size and position of a menu if scalable layouts are available.
       
  6935 // Also sets the rectangular for the menu pane
       
  6936 // -----------------------------------------------------------------------------
       
  6937 //
       
  6938 TRect CEikMenuPane::CalculateSizeAndPositionScalable( const TRect& aWindowRect, TInt aNumItemsInPane )
       
  6939     {
       
  6940     __ASSERT_ALWAYS( iExtension, Panic( EEikPanicNullPointer ) );
       
  6941     _AKNTRACE_FUNC_ENTER;
       
  6942     TRect retVal;
       
  6943 
       
  6944     // it can be only in submenu in case when scalable layout is available
       
  6945     TBool hasIcon = MenuHasIcon();
       
  6946     TBool hasDoubleSpanScrollBar = EFalse;
       
  6947 
       
  6948     if ( iSBFrame && iSBFrame->VScrollBarVisibility() )
       
  6949         {
       
  6950         _AKNTRACE( "[%s]", "hasDoubleSpanScrollBar = ETrue;" );
       
  6951         hasDoubleSpanScrollBar = ETrue;
       
  6952         }
       
  6953 
       
  6954     TRect parentMenuRect;
       
  6955     AknLayoutUtils::TAknCbaLocation cbaPosition = AknLayoutUtils::CbaLocation();    
       
  6956                 
       
  6957     if ( !iOwner )
       
  6958         {
       
  6959         _AKNTRACE( "[%s]", "the laylout of mainmenu" );
       
  6960         TAknLayoutRect parentMenuLayoutRect;     // popup_menu_window
       
  6961 
       
  6962         // This is a parent menu pane
       
  6963 
       
  6964         // Number of items and cba position tells the right layout for menu pane.
       
  6965         // Constants (33, 20, 7) and calculations are based on to the variants of the layout data.
       
  6966         switch ( cbaPosition )
       
  6967             {
       
  6968             case AknLayoutUtils::EAknCbaLocationLeft:
       
  6969                 {
       
  6970                 _AKNTRACE( "[%s]", "AknLayoutUtils::EAknCbaLocationLeft" );
       
  6971                 switch ( aNumItemsInPane )
       
  6972                     {
       
  6973                     case 7:
       
  6974                     case 8:
       
  6975                         {
       
  6976                         parentMenuLayoutRect.LayoutRect( aWindowRect,
       
  6977                             AknLayoutScalable_Avkon::popup_menu_window(37 + aNumItemsInPane).LayoutLine());
       
  6978     
       
  6979                         break;                  
       
  6980                         }
       
  6981                     default:
       
  6982                         parentMenuLayoutRect.LayoutRect( aWindowRect,
       
  6983                             AknLayoutScalable_Avkon::popup_menu_window(33 - aNumItemsInPane).LayoutLine());
       
  6984                         break;
       
  6985                     }
       
  6986                 break;                
       
  6987                 }
       
  6988             case AknLayoutUtils::EAknCbaLocationRight:
       
  6989                 {
       
  6990                 _AKNTRACE( "[%s]", "AknLayoutUtils::EAknCbaLocationRight" );
       
  6991                 TRect windowRect;
       
  6992                 AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EPopupParent, windowRect );
       
  6993                 
       
  6994                 switch ( aNumItemsInPane )
       
  6995                     {
       
  6996                     case 7:
       
  6997                     case 8:
       
  6998                         {
       
  6999                         parentMenuLayoutRect.LayoutRect( windowRect,
       
  7000                             AknLayoutScalable_Avkon::popup_menu_window(35 + aNumItemsInPane).LayoutLine());      
       
  7001                         break;                  
       
  7002                         }
       
  7003                     default:
       
  7004                         parentMenuLayoutRect.LayoutRect( windowRect,
       
  7005                             AknLayoutScalable_Avkon::popup_menu_window(20 - aNumItemsInPane).LayoutLine());
       
  7006                         break;
       
  7007                     }
       
  7008                 break;
       
  7009                 }
       
  7010             case AknLayoutUtils::EAknCbaLocationBottom:
       
  7011                 {
       
  7012                 _AKNTRACE( "[%s]", "AknLayoutUtils::EAknCbaLocationBottom" );
       
  7013                 switch ( aNumItemsInPane )
       
  7014                     {
       
  7015                     case 7:
       
  7016                     case 8:
       
  7017                         {
       
  7018                         parentMenuLayoutRect.LayoutRect( aWindowRect,
       
  7019                             AknLayoutScalable_Avkon::popup_menu_window(33 + aNumItemsInPane).LayoutLine());
       
  7020                         break;                  
       
  7021                         }
       
  7022                     default:
       
  7023                         parentMenuLayoutRect.LayoutRect( aWindowRect,
       
  7024                             AknLayoutScalable_Avkon::popup_menu_window(7 + aNumItemsInPane).LayoutLine());
       
  7025                         break;
       
  7026                     }
       
  7027                 break;
       
  7028                 }
       
  7029             default:
       
  7030                 break;
       
  7031             }
       
  7032         parentMenuRect = parentMenuLayoutRect.Rect();
       
  7033         }
       
  7034     else
       
  7035         {
       
  7036         _AKNTRACE( "[%s]", "the layout of submenu" );
       
  7037         // submenu
       
  7038         parentMenuRect = TRect( iOwner->Position(), iOwner->Size() );
       
  7039         }
       
  7040 
       
  7041     _AKNTRACE( "parentMenuRect.iTl.iX = %d", parentMenuRect.iTl.iX );
       
  7042     _AKNTRACE( "parentMenuRect.iTl.iY = %d", parentMenuRect.iTl.iY );
       
  7043     _AKNTRACE( "parentMenuRect.Width() = %d", parentMenuRect.Width() );
       
  7044     _AKNTRACE( "parentMenuRect.Height( = %d", parentMenuRect.Height() );
       
  7045     // if we have landscape layout then main menu should be positioned vertically centered
       
  7046     TRect appRect( iEikonEnv->EikAppUi()->ApplicationRect() );
       
  7047 
       
  7048     if ( !iOwner ) // main menu
       
  7049         {
       
  7050         // Embedded cba
       
  7051         TRect screen;
       
  7052         AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EScreen, screen );
       
  7053         
       
  7054         TAknLayoutRect cbaRect;
       
  7055         cbaRect.LayoutRect( screen, 
       
  7056             AknLayoutScalable_Avkon::popup_sk_window( 0  ).LayoutLine() );
       
  7057 
       
  7058         // Add space for embedded cba
       
  7059         TRect menuRect ( parentMenuRect );
       
  7060         parentMenuRect.iBr.iY += ( cbaRect.Rect().Height() );
       
  7061 
       
  7062         // CEikMenuPane rect contains empty space. We want the popup content
       
  7063         // to be in correct place - so we calculate correct position for
       
  7064         // background and move control rect to match new background top left
       
  7065         // position.
       
  7066         TRect backgroundRect( iExtension->GetBackgroundRect( parentMenuRect ) );
       
  7067         TPoint backgroundRectPos( 
       
  7068             AknPopupUtils::Position( backgroundRect.Size(), ETrue ) );
       
  7069         
       
  7070         retVal = parentMenuRect;
       
  7071         retVal.Move( backgroundRectPos - backgroundRect.iTl );
       
  7072         
       
  7073         // Set embedded cba rect
       
  7074         if ( iExtension->iCba )
       
  7075             {
       
  7076             // There is hidden extra touch space for scroll bar in landscape
       
  7077             TInt xOffset = backgroundRect.iTl.iX - parentMenuRect.iTl.iX ; 
       
  7078             iExtension->iCba->SetRect( TRect( 
       
  7079                 xOffset,
       
  7080                 menuRect.Height(),
       
  7081                 backgroundRect.Width() + xOffset,
       
  7082                 menuRect.Height() + cbaRect.Rect().Height() ) );
       
  7083             }
       
  7084 
       
  7085         iExtension->iMenuPaneRect = TRect( retVal.iTl, 
       
  7086                                            TSize ( menuRect.Size() ) );
       
  7087                                         
       
  7088         _AKNTRACE( "[%s]", "the layout of main menu return" );
       
  7089         _AKNTRACE_FUNC_EXIT;                               
       
  7090         return retVal;
       
  7091         }
       
  7092 
       
  7093     // This is a cascaded sub menu
       
  7094     // Get a rectangle for the Parent Menu (iOwner)
       
  7095     TInt parentCount = iOwner->iItemArray->Count(); // There must be at least one parent item for a submenu to have popped up.
       
  7096 
       
  7097     iExtension->iSubMenuWidthIndex = KAlternativeSubmenuWidths - 1;
       
  7098 
       
  7099     TAknLayoutRect parentListScrollLayoutRect;     // listscroll_menu_pane
       
  7100     TAknLayoutRect parentPaneLayoutRect;           // list_menu_pane
       
  7101 
       
  7102     TAknTextLineLayout subMenuText;                // layout for the text when item is not indicated
       
  7103     TAknTextLineLayout subMenuIconText;            // layout for the text when item is indicated
       
  7104 
       
  7105     TAknWindowLineLayout parentListScrollPaneLayout( 
       
  7106         AknLayoutScalable_Avkon::listscroll_menu_pane(0).LayoutLine() );
       
  7107     if ( iExtension )
       
  7108         {
       
  7109         iExtension->AdjustPopupLayoutData( parentListScrollPaneLayout );
       
  7110         }    
       
  7111     parentListScrollLayoutRect.LayoutRect( parentMenuRect, parentListScrollPaneLayout );    
       
  7112     parentPaneLayoutRect.LayoutRect( parentListScrollLayoutRect.Rect(),
       
  7113         AknLayoutScalable_Avkon::list_menu_pane(0).LayoutLine() );
       
  7114     subMenuText = AknLayoutScalable_Avkon::list_single_popup_submenu_pane_t1(0).LayoutLine();
       
  7115     subMenuIconText = AknLayoutScalable_Avkon::list_single_popup_submenu_pane_t1(1).LayoutLine();
       
  7116 
       
  7117     // Choose correct submenu width
       
  7118     // Find the narrowest layout that will accommodate the text
       
  7119     // Need the font.
       
  7120     const CFont* font = AknLayoutUtils::FontFromId( subMenuIconText.FontId() );
       
  7121     // find the longest piece of text
       
  7122     TInt textWidth = 0;
       
  7123     TInt maxTextWidth = 0;
       
  7124     TInt ii = 0;
       
  7125     
       
  7126     TInt count = (NULL != iItemArray) ? iItemArray->Count() : 0;
       
  7127 
       
  7128     for (ii = 0; ii < count; ++ii)
       
  7129         {
       
  7130         CEikMenuPaneItem* item = (*iItemArray)[ii];
       
  7131         textWidth = font->TextWidthInPixels( item->iData.iText );
       
  7132         maxTextWidth = Max( maxTextWidth, textWidth );
       
  7133         }
       
  7134 
       
  7135     // find the suitable item width, so that the text would be visible
       
  7136     for ( ii = 6; ii < KAlternativeSubmenuWidths + 6; ++ii )
       
  7137         {
       
  7138         TAknWindowLineLayout submenuLayout( AknLayoutScalable_Avkon::popup_submenu_window( ii ).LayoutLine() );
       
  7139         TAknLayoutRect submenuRect;
       
  7140         submenuRect.LayoutRect( parentListScrollLayoutRect.Rect(), submenuLayout );
       
  7141 
       
  7142         TAknWindowLineLayout listScrollPaneLayout( AknLayoutScalable_Avkon::listscroll_popup_sub_pane().LayoutLine() );
       
  7143         TAknLayoutRect listScrollPaneRect;
       
  7144         listScrollPaneRect.LayoutRect( submenuRect.Rect(), listScrollPaneLayout );
       
  7145 
       
  7146         TAknWindowLineLayout listSubmenuPaneLayout( AknLayoutScalable_Avkon::list_submenu_pane( !hasDoubleSpanScrollBar ).LayoutLine() );
       
  7147         TAknLayoutRect listSubmenuPaneRect;
       
  7148         listSubmenuPaneRect.LayoutRect( listScrollPaneRect.Rect(), listSubmenuPaneLayout );
       
  7149 
       
  7150         TAknLayoutText textIconLayout;
       
  7151         textIconLayout.LayoutText( listSubmenuPaneRect.Rect(), subMenuIconText);
       
  7152 
       
  7153         TAknLayoutText textLayout;
       
  7154         textLayout.LayoutText( listSubmenuPaneRect.Rect(), subMenuText);
       
  7155 
       
  7156         TInt width = textLayout.TextRect().Width();
       
  7157         TInt maxWidth( maxTextWidth );
       
  7158 
       
  7159         if ( hasIcon )
       
  7160             {
       
  7161             // this is needed to calculate right index, because they are for the case when there is no indication
       
  7162             TInt difference = textIconLayout.TextRect().iTl.iX - textLayout.TextRect().iTl.iX;
       
  7163             maxWidth = maxTextWidth + difference;
       
  7164             width = textIconLayout.TextRect().Width();
       
  7165             }
       
  7166 
       
  7167         if ( width >= maxWidth)
       
  7168             {
       
  7169             iExtension->iSubMenuWidthIndex = ii - 6; // finally we found one
       
  7170             break;
       
  7171             }
       
  7172         }
       
  7173 
       
  7174     // Position of submenu depends upon parent size and position of selected item. Position is 1 at bottom up to six at top
       
  7175     TInt parentPos = iOwner->iScroller->TopItemIndex() - iOwner->SelectedItem() +
       
  7176         Min( parentCount, iOwner->NumberOfItemsThatFitInView() );
       
  7177 
       
  7178     TInt index =  iOwner->SelectedItem() - iOwner->iScroller->TopItemIndex();
       
  7179     TInt rows = AknLayoutScalable_Avkon::list_single_pane_cp2_ParamLimits().LastRow();
       
  7180 
       
  7181     // This condition may be true if less items fits to menu view than sub-menu view
       
  7182     // and sub-menu under sub-menu is launched.
       
  7183     if (index > rows)
       
  7184         {
       
  7185         // Change the out-of-boundary index to last legal one.
       
  7186         index = rows;
       
  7187         }
       
  7188 
       
  7189     TAknLayoutRect parentSelectedItemRect;
       
  7190     parentSelectedItemRect.LayoutRect( parentPaneLayoutRect.Rect(),
       
  7191         AknLayoutScalable_Avkon::list_single_pane_cp2( index ).LayoutLine() );
       
  7192 
       
  7193     TAknLayoutRect submenuWindowRect;
       
  7194     // To prevent a panic in layout code, count has to be at least 1 even if
       
  7195     // submenu is empty. Otherwise the index is out of bounds.
       
  7196     if ( count == 0 )
       
  7197         {
       
  7198         count++;
       
  7199         }
       
  7200     TInt maxItems = NumberOfItemsThatFitInView();
       
  7201     submenuWindowRect.LayoutRect( parentMenuRect,
       
  7202         AknLayoutScalable_Avkon::popup_submenu_window( Min( count, maxItems ) - 1 ).LayoutLine() );
       
  7203     // if submenu is higher than main menu, we should not allow it to cover softkeys in landscape
       
  7204     // the same should be done if position of the menu was set from outside.
       
  7205     if ( ( Layout_Meta_Data::IsLandscapeOrientation()
       
  7206         && cbaPosition != AknLayoutUtils::EAknCbaLocationBottom &&
       
  7207         ( submenuWindowRect.Rect().Height() > parentMenuRect.Height() ) ) )
       
  7208         {
       
  7209         // submenu should stay inside main menu by width,
       
  7210         TRect bufRect( aWindowRect );
       
  7211         bufRect.iTl.iX = parentMenuRect.iTl.iX;
       
  7212         bufRect.iBr.iX = parentMenuRect.iBr.iX;
       
  7213         submenuWindowRect.LayoutRect( bufRect,
       
  7214             AknLayoutScalable_Avkon::popup_submenu_window( Min( count, maxItems ) - 1 ).LayoutLine() );
       
  7215         }
       
  7216 
       
  7217     TAknLayoutRect widthSubmenuRect;
       
  7218     widthSubmenuRect.LayoutRect( parentMenuRect,
       
  7219         AknLayoutScalable_Avkon::popup_submenu_window( iExtension->iSubMenuWidthIndex + 6 ).LayoutLine() );
       
  7220 
       
  7221     TAknWindowLineLayout listScrollPaneLayout( AknLayoutScalable_Avkon::listscroll_popup_sub_pane().LayoutLine() );
       
  7222     TAknLayoutRect listScrollPaneRect;
       
  7223     listScrollPaneRect.LayoutRect( submenuWindowRect.Rect(), listScrollPaneLayout );
       
  7224 
       
  7225     enum { EFloating, EBottom } subMenuPos;
       
  7226 
       
  7227     if ( ( Layout_Meta_Data::IsLandscapeOrientation()
       
  7228         && cbaPosition != AknLayoutUtils::EAknCbaLocationBottom ) )
       
  7229         {
       
  7230         if ( ( parentSelectedItemRect.Rect().iTl.iY + submenuWindowRect.Rect().Height() ) >
       
  7231                 aWindowRect.iBr.iY )
       
  7232             {
       
  7233             subMenuPos = EBottom;
       
  7234             }
       
  7235         else
       
  7236             {
       
  7237             subMenuPos = EFloating;
       
  7238             }
       
  7239         }
       
  7240     else
       
  7241         {
       
  7242         if ( iOwner->iExtension->Offset() < 0 &&
       
  7243             ((parentPos == 1 && count == 1) || 
       
  7244             (parentPos == 2 && count <= 2) ||
       
  7245             (parentPos == 3 && count <= 3) ||
       
  7246             (parentPos == 4 && count <= 4) ||
       
  7247             (parentPos == 5 && count <= 5)  )  )
       
  7248             {
       
  7249             // The menu has partial items because of panning and that has an effect on submenu positioning.
       
  7250             subMenuPos = EFloating;
       
  7251             }
       
  7252         else if (parentPos == 1 ||
       
  7253                  (parentPos ==2 && count >= 2) ||
       
  7254                  (parentPos == 3 && count >= 4) ||
       
  7255                  (parentPos == 4 && count >= 5) ||
       
  7256                  (parentPos == 5 && count >= 6) )
       
  7257             {
       
  7258             subMenuPos = EBottom;
       
  7259             }
       
  7260         else
       
  7261             {
       
  7262             subMenuPos = EFloating;
       
  7263             }
       
  7264         }
       
  7265 
       
  7266     if ( subMenuPos == EBottom )
       
  7267         {
       
  7268         TInt widthOffset = widthSubmenuRect.Rect().Width() - submenuWindowRect.Rect().Width();
       
  7269         if ( !AknLayoutUtils::LayoutMirrored() )
       
  7270             {
       
  7271             retVal = TRect( TPoint( submenuWindowRect.Rect().iTl.iX - widthOffset, submenuWindowRect.Rect().iTl.iY ),
       
  7272                 TSize( submenuWindowRect.Rect().Width() + widthOffset, submenuWindowRect.Rect().Height() ) );
       
  7273             }
       
  7274         else
       
  7275             {
       
  7276             retVal = TRect( submenuWindowRect.Rect().iTl,
       
  7277                 TSize( submenuWindowRect.Rect().Width() + widthOffset, submenuWindowRect.Rect().Height() ) );
       
  7278             }
       
  7279         }
       
  7280     else  // floating
       
  7281         {
       
  7282         TInt yPos = parentSelectedItemRect.Rect().iTl.iY -
       
  7283             ( listScrollPaneRect.Rect().iTl.iY - submenuWindowRect.Rect().iTl.iY );
       
  7284 
       
  7285         // When a submenu is floating, make sure that the possible panning offset of the
       
  7286         // parent menu is taken into account.
       
  7287         yPos += iOwner->iExtension->Offset();
       
  7288         TInt widthOffset = widthSubmenuRect.Rect().Width() - submenuWindowRect.Rect().Width();
       
  7289         if ( !AknLayoutUtils::LayoutMirrored() )
       
  7290             {
       
  7291             retVal = TRect( TPoint( submenuWindowRect.Rect().iTl.iX - widthOffset, yPos ),
       
  7292                 TSize( submenuWindowRect.Rect().Width() + widthOffset, submenuWindowRect.Rect().Height() ) );
       
  7293             }
       
  7294         else
       
  7295             {
       
  7296             retVal = TRect( TPoint( submenuWindowRect.Rect().iTl.iX, yPos ),
       
  7297                 TSize( submenuWindowRect.Rect().Width() + widthOffset, submenuWindowRect.Rect().Height() ) );
       
  7298             }
       
  7299         }
       
  7300 
       
  7301     // move submenu if it overlaps with embedded cba
       
  7302     if ( iOwner && iOwner->iExtension->iCba )
       
  7303         {
       
  7304         if ( retVal.iBr.iY > iOwner->iExtension->iMenuPaneRect.iBr.iY )
       
  7305             {
       
  7306             TInt offset = retVal.iBr.iY - 
       
  7307                 iOwner->iExtension->iMenuPaneRect.iBr.iY;
       
  7308             retVal.Move( 0, -offset );
       
  7309             }
       
  7310         }
       
  7311     _AKNTRACE( "[%s]", "the layout of sub menu return" );
       
  7312     _AKNTRACE_FUNC_EXIT;  
       
  7313     return retVal;
       
  7314     }
       
  7315 
       
  7316 // -----------------------------------------------------------------------------
       
  7317 // CEikMenuPane::HighlightRect
       
  7318 // -----------------------------------------------------------------------------
       
  7319 //
       
  7320 TRect CEikMenuPane::HighlightRect() const
       
  7321     {
       
  7322     TInt index = iSelectedItem - iScroller->TopItemIndex();
       
  7323 
       
  7324     // If menu is closed and the selected item index is outside the visible
       
  7325     // item range this method is called with new iSelectedItem and old
       
  7326     // TopItemIndex. Which results in negative index. This "fix" prevents from
       
  7327     // crashing the menu.
       
  7328     if( index < 0 )
       
  7329         index = 0;
       
  7330 
       
  7331     // It is possible that this method is called when iItemArray is NULL.  In
       
  7332     // that case we fake numItems as 1 to make layout code work.
       
  7333     TInt maxItems = NumberOfItemsThatFitInView();
       
  7334     TInt numItems = Min( Max( 1, iItemArray->Count() ), maxItems );
       
  7335     if( !iItemArray )
       
  7336         numItems = 1;
       
  7337     
       
  7338     // When physics is enabled highlight can be moved to partially visible
       
  7339     // item which is at the bottom of menu. This causes layout panic and to 
       
  7340     // avoid that we reduce index by one.
       
  7341     if ( index == maxItems )
       
  7342         {
       
  7343         index--;
       
  7344         }
       
  7345    
       
  7346     TRect windowRect = Rect();
       
  7347 
       
  7348     TAknWindowLineLayout menuPane( AKN_LAYOUT_WINDOW_list_menu_pane( 0 , 0 ) );
       
  7349     TAknWindowLineLayout singleMenuPane( AKN_LAYOUT_WINDOW_list_single_popup_menu_pane( index ) );
       
  7350     TAknLayoutRect menuPaneRect;
       
  7351     TAknLayoutRect singleMenuPaneRect;
       
  7352 
       
  7353     TBool hasDoubleSpanScrollBar = EFalse;
       
  7354 
       
  7355     if ( iSBFrame && iSBFrame->VScrollBarVisibility() )
       
  7356         {
       
  7357         hasDoubleSpanScrollBar = ETrue;
       
  7358         }
       
  7359 
       
  7360     if ( !iOwner )
       
  7361         {
       
  7362         TAknWindowLineLayout listScrollPaneLayout( 
       
  7363             AknLayoutScalable_Avkon::listscroll_menu_pane(0).LayoutLine() );
       
  7364         if ( iExtension )
       
  7365             {
       
  7366             iExtension->AdjustPopupLayoutData( listScrollPaneLayout );
       
  7367             }                            
       
  7368         TAknLayoutRect listScrollPaneRect;
       
  7369         listScrollPaneRect.LayoutRect( windowRect, listScrollPaneLayout );
       
  7370 
       
  7371         menuPane = AknLayoutScalable_Avkon::list_menu_pane( 0 ).LayoutLine();
       
  7372         menuPaneRect.LayoutRect( listScrollPaneRect.Rect(), menuPane );
       
  7373 
       
  7374         singleMenuPane = AknLayoutScalable_Avkon::list_single_pane_cp2( index ).LayoutLine();
       
  7375         singleMenuPaneRect.LayoutRect( menuPaneRect.Rect(), singleMenuPane );
       
  7376         }
       
  7377     else // Submenu
       
  7378         {
       
  7379         TAknWindowLineLayout listScrollPaneLayout( AknLayoutScalable_Avkon::listscroll_popup_sub_pane().LayoutLine() );
       
  7380         TAknLayoutRect listScrollPaneRect;
       
  7381         listScrollPaneRect.LayoutRect( windowRect, listScrollPaneLayout );
       
  7382 
       
  7383         menuPane = AknLayoutScalable_Avkon::list_submenu_pane( !hasDoubleSpanScrollBar ).LayoutLine();
       
  7384         menuPaneRect.LayoutRect( listScrollPaneRect.Rect(), menuPane );
       
  7385 
       
  7386         singleMenuPane = AknLayoutScalable_Avkon::list_single_popup_submenu_pane( index ).LayoutLine();
       
  7387         singleMenuPaneRect.LayoutRect( menuPaneRect.Rect(), singleMenuPane );
       
  7388         }
       
  7389 
       
  7390     // Compared to normal DrawItem the highlight rect step is omitted because
       
  7391     // it would shift the highlight towards left.
       
  7392 
       
  7393     return singleMenuPaneRect.Rect();
       
  7394     }
       
  7395 
       
  7396 
       
  7397 // -----------------------------------------------------------------------------
       
  7398 // CEikMenuPane::PrepareHighlightFrame
       
  7399 // helps to avoid flickering on drawing
       
  7400 // -----------------------------------------------------------------------------
       
  7401 //
       
  7402 void CEikMenuPane::PrepareHighlightFrame() const
       
  7403     {
       
  7404     TRect highlightRect( HighlightRect() );
       
  7405     TAknLayoutRect highlightTopLeft;
       
  7406     TAknLayoutRect highlightBottomRight;
       
  7407     highlightTopLeft.LayoutRect( highlightRect,
       
  7408         SkinLayout::List_highlight_skin_placing__popup_windows__Line_2() );
       
  7409     highlightBottomRight.LayoutRect( highlightRect,
       
  7410         SkinLayout::List_highlight_skin_placing__popup_windows__Line_5() );
       
  7411     TRect outerRect = TRect( highlightTopLeft.Rect().iTl, highlightBottomRight.Rect().iBr );
       
  7412     TRect innerRect = TRect( highlightTopLeft.Rect().iBr, highlightBottomRight.Rect().iTl );
       
  7413     MAknsSkinInstance* skin = AknsUtils::SkinInstance();
       
  7414 
       
  7415     AknsDrawUtils::PrepareFrame( skin, outerRect, innerRect,
       
  7416                                  KAknsIIDQsnFrList, KAknsIIDDefault );
       
  7417     }
       
  7418 
       
  7419 // -----------------------------------------------------------------------------
       
  7420 // CEikMenuPane::SetCascadedIconSize
       
  7421 // Calls SetSize for cascaded icon. Doing this in construction phase makes
       
  7422 // Draw() method faster.
       
  7423 // -----------------------------------------------------------------------------
       
  7424 //
       
  7425 void CEikMenuPane::SetCascadedIconSize() const
       
  7426     {
       
  7427     TAknWindowLineLayout elementCascade( AknLayoutScalable_Avkon::list_single_pane_cp2_g3().LayoutLine());
       
  7428     TAknLayoutRect cascadeRect;
       
  7429     cascadeRect.LayoutRect( HighlightRect(), elementCascade );
       
  7430 
       
  7431     MAknsSkinInstance* skin = AknsUtils::SkinInstance();
       
  7432     CAknsMaskedBitmapItemData* itemData = static_cast<CAknsMaskedBitmapItemData*>(
       
  7433         skin->GetCachedItemData( KAknsIIDQgnIndiSubmenu, EAknsITMaskedBitmap ) );
       
  7434 
       
  7435     if( itemData )
       
  7436         {
       
  7437         AknIconUtils::SetSize( itemData->Bitmap(),  cascadeRect.Rect().Size() );
       
  7438         }
       
  7439 
       
  7440     else
       
  7441         {
       
  7442         if (iExtension->iCascadeBitmap)
       
  7443             {
       
  7444             AknIconUtils::SetSize( iExtension->iCascadeBitmap,  cascadeRect.Rect().Size() );
       
  7445             }
       
  7446         }
       
  7447     }
       
  7448 
       
  7449 
       
  7450 // -----------------------------------------------------------------------------
       
  7451 // CEikMenuPane::EnableMarqueeL
       
  7452 // -----------------------------------------------------------------------------
       
  7453 //
       
  7454 EXPORT_C void CEikMenuPane::EnableMarqueeL( const TBool /*aEnable*/ )
       
  7455     {
       
  7456     }
       
  7457 
       
  7458 
       
  7459 // -----------------------------------------------------------------------------
       
  7460 // CEikMenuPane::MopSupplyObject
       
  7461 // -----------------------------------------------------------------------------
       
  7462 //
       
  7463 EXPORT_C TTypeUid::Ptr CEikMenuPane::MopSupplyObject( TTypeUid aId )
       
  7464     {
       
  7465     if( aId.iUid == MAknsControlContext::ETypeId && iExtension && iExtension->iBgContext )
       
  7466         {
       
  7467         // Supply background skin context for scroll bars.
       
  7468         return MAknsControlContext::SupplyMopObject( aId, iExtension->iBgContext);
       
  7469         }
       
  7470 
       
  7471     return CCoeControl::MopSupplyObject( aId );
       
  7472     }
       
  7473 
       
  7474 
       
  7475 // -----------------------------------------------------------------------------
       
  7476 // CEikMenuPane::CountComponentControls
       
  7477 // -----------------------------------------------------------------------------
       
  7478 //
       
  7479 EXPORT_C TInt CEikMenuPane::CountComponentControls() const
       
  7480     {
       
  7481     TInt count = 0;
       
  7482     if ( iSBFrame && iSBFrame->VerticalScrollBar() &&
       
  7483                             !( iSBFrame->VerticalScrollBar()->OwnsWindow() ) )
       
  7484         {
       
  7485         count = 1;
       
  7486         }
       
  7487     if ( iExtension->iSct )
       
  7488         {
       
  7489         count++;
       
  7490         }
       
  7491 
       
  7492     if ( iExtension->iCba )        
       
  7493         {
       
  7494         count++;
       
  7495         }
       
  7496 
       
  7497     return count;
       
  7498     }
       
  7499 
       
  7500 // -----------------------------------------------------------------------------
       
  7501 // CEikMenuPane::ComponentControl
       
  7502 // -----------------------------------------------------------------------------
       
  7503 //
       
  7504 EXPORT_C CCoeControl* CEikMenuPane::ComponentControl( TInt aIndex ) const
       
  7505     {
       
  7506     switch ( aIndex)
       
  7507         {
       
  7508         case 0:
       
  7509             {
       
  7510             if ( iSBFrame && iSBFrame->VerticalScrollBar() &&
       
  7511                         !( iSBFrame->VerticalScrollBar()->OwnsWindow() ) )
       
  7512                 {
       
  7513                 return iSBFrame->VerticalScrollBar();
       
  7514                 }
       
  7515             }
       
  7516         case 1:
       
  7517             {
       
  7518             if ( iExtension->iSct )
       
  7519                 {
       
  7520                 return iExtension->iSct;
       
  7521                 }
       
  7522             else if ( iExtension->iCba )
       
  7523                 {
       
  7524                 return iExtension->iCba;
       
  7525                 }
       
  7526             }
       
  7527         case 2:
       
  7528             {
       
  7529             if ( iExtension->iCba )
       
  7530                 {
       
  7531                 return iExtension->iCba;
       
  7532                 }
       
  7533             }
       
  7534         default:
       
  7535             {
       
  7536             return NULL;
       
  7537             }
       
  7538         }
       
  7539     }
       
  7540 
       
  7541 
       
  7542 // -----------------------------------------------------------------------------
       
  7543 // CEikMenuPane::Extension
       
  7544 // Asserts that extension object has been created.
       
  7545 // -----------------------------------------------------------------------------
       
  7546 //
       
  7547 CEikMenuPaneExtension* CEikMenuPane::Extension() const
       
  7548     {
       
  7549     __ASSERT_ALWAYS( iExtension, Panic( EEikPanicNullPointer ) );
       
  7550     return iExtension;
       
  7551     }
       
  7552 
       
  7553 
       
  7554 void CEikMenuPane::CheckCreateExtensionL()
       
  7555     {
       
  7556     if ( !iExtension )
       
  7557         {
       
  7558         iExtension = new (ELeave) CEikMenuPaneExtension;
       
  7559         iExtension->ConstructL( this );
       
  7560         }
       
  7561     }
       
  7562 
       
  7563 
       
  7564 // -----------------------------------------------------------------------------
       
  7565 // CEikMenuPane::ConstructMenuSctRowL
       
  7566 // Creates an sct row for editing menu.
       
  7567 // @param aSpecialChars Buffer that holds selected characters
       
  7568 // @since 3.1
       
  7569 // -----------------------------------------------------------------------------
       
  7570 //
       
  7571 EXPORT_C void CEikMenuPane::ConstructMenuSctRowL( TDes& aSpecialChars )
       
  7572     {
       
  7573     CheckCreateScrollerL();
       
  7574     CheckCreateExtensionL();
       
  7575 
       
  7576     TInt resourceId = R_AVKON_MENU_SCT_ROW_DEFAULT_CONTENTS;
       
  7577     if (FeatureManager::FeatureSupported(KFeatureIdChinese))
       
  7578         {
       
  7579         resourceId = R_AVKON_MENU_SCT_ROW_DEFAULT_CONTENTS_CHINESE;
       
  7580         }
       
  7581     iExtension->ConstructMenuSctRowL( aSpecialChars, resourceId );
       
  7582     }
       
  7583 
       
  7584 // -----------------------------------------------------------------------------
       
  7585 // CEikMenuPane::ConstructMenuSctRowL
       
  7586 // Creates an sct row for editing menu.
       
  7587 // @param aSpecialChars Buffer that holds selected characters
       
  7588 // @since 3.1
       
  7589 // -----------------------------------------------------------------------------
       
  7590 //
       
  7591 
       
  7592 EXPORT_C void CEikMenuPane::ConstructMenuSctRowL( TDes& aSpecialChars, TInt aResourceId )
       
  7593     {
       
  7594     CheckCreateScrollerL();
       
  7595     CheckCreateExtensionL();
       
  7596     iExtension->ConstructMenuSctRowL( aSpecialChars, aResourceId );
       
  7597     }
       
  7598 
       
  7599 // -----------------------------------------------------------------------------
       
  7600 // CEikMenuPane::ConstructMenuSctRowFromDialogL
       
  7601 // Creates an sct row for editing menu.
       
  7602 // @param aSpecialChars Buffer that holds selected characters
       
  7603 // @since 3.1
       
  7604 // -----------------------------------------------------------------------------
       
  7605 //
       
  7606 EXPORT_C void CEikMenuPane::ConstructMenuSctRowFromDialogL( TDes& aSpecialChars, TInt aResourceId )
       
  7607     {
       
  7608     CheckCreateScrollerL();
       
  7609     CheckCreateExtensionL();
       
  7610     iExtension->ConstructMenuSctRowFromDialogL( aSpecialChars, aResourceId );
       
  7611     }
       
  7612 
       
  7613 // -----------------------------------------------------------------------------
       
  7614 // CEikMenuPane::ConstructMenuSctRowFromDialogL
       
  7615 // Creates an sct row for editing menu.
       
  7616 // @param aSpecialChars Buffer that holds selected characters
       
  7617 // @since 3.1
       
  7618 // -----------------------------------------------------------------------------
       
  7619 //
       
  7620 EXPORT_C void CEikMenuPane::ConstructMenuSctRowFromDialogL( TInt aCharCase, TDes& aSpecialChars, TInt aResourceId )
       
  7621     {
       
  7622     ConstructMenuSctRowFromDialogL( aSpecialChars, aResourceId);
       
  7623     iExtension->iSct->SetCharacterCaseL(aCharCase);
       
  7624     }
       
  7625 
       
  7626 
       
  7627 // -----------------------------------------------------------------------------
       
  7628 // CEikMenuPane::SetItemSpecific
       
  7629 // -----------------------------------------------------------------------------
       
  7630 //
       
  7631 EXPORT_C void CEikMenuPane::SetItemSpecific(
       
  7632         TInt aCommandId, TBool aItemSpecific )
       
  7633     {
       
  7634     if ( iExtension->iFlags.IsSet(
       
  7635             CEikMenuPaneExtension::ESingleClickEnabled ) )
       
  7636         {
       
  7637         CEikMenuPaneItem::SData& itemData = ItemData( aCommandId );
       
  7638         if ( aItemSpecific )
       
  7639             {
       
  7640             // item specific command cannot be item action command
       
  7641             itemData.iFlags &= ( ~EEikMenuItemAction );
       
  7642             itemData.iFlags |= EEikMenuItemSpecific;
       
  7643             }
       
  7644         else
       
  7645             {
       
  7646             // clear both item specific flags
       
  7647             itemData.iFlags &= ( ~EEikMenuItemSpecific );
       
  7648             itemData.iFlags &= ( ~EEikMenuItemSpecificListQuery );
       
  7649             }
       
  7650         }
       
  7651     }
       
  7652 
       
  7653 
       
  7654 // -----------------------------------------------------------------------------
       
  7655 // CEikMenuPane::MenuItemCommandId
       
  7656 // Returns the command id of the specified menu item.
       
  7657 // -----------------------------------------------------------------------------
       
  7658 //
       
  7659 EXPORT_C TInt CEikMenuPane::MenuItemCommandId( const TInt aIndex ) const
       
  7660     {
       
  7661     if ( !iItemArray || aIndex >= iItemArray->Count() || aIndex < 0 )
       
  7662         {
       
  7663         Panic( EEikPanicInvalidIndex );
       
  7664         }
       
  7665     CEikMenuPaneItem* item = (*iItemArray)[aIndex];
       
  7666     if ( !item )
       
  7667         {
       
  7668         Panic( EEikPanicNullPointer );
       
  7669         }
       
  7670     return item->iData.iCommandId;
       
  7671     }
       
  7672 
       
  7673 
       
  7674 // -----------------------------------------------------------------------------
       
  7675 // CEikMenuPane::SetEmbeddedCba
       
  7676 // -----------------------------------------------------------------------------
       
  7677 //
       
  7678 void CEikMenuPane::SetEmbeddedCba( CEikCba* aCba )
       
  7679     {
       
  7680     if ( iExtension )
       
  7681         {
       
  7682         iExtension->iCba = aCba;
       
  7683         }
       
  7684     }
       
  7685 
       
  7686 
       
  7687 // -----------------------------------------------------------------------------
       
  7688 // CEikMenuPane::CloseCascadeMenu
       
  7689 // -----------------------------------------------------------------------------
       
  7690 //
       
  7691 void CEikMenuPane::CloseCascadeMenu( TBool aMainMenuClosing )
       
  7692     {
       
  7693     if ( iCascadeMenuPane == NULL )
       
  7694         {
       
  7695         return;
       
  7696         }
       
  7697     if( iCascadeMenuPane->iCascadeMenuPane)
       
  7698         {
       
  7699         return iCascadeMenuPane->CloseCascadeMenu();    
       
  7700         }
       
  7701 
       
  7702     // This CloseCascadeMenu method is called from CEikMenuPane destructor.
       
  7703     // CEikMenuPane may be destroyed in AppUi's destructor.
       
  7704     // Thus, skin instance may not be valid any more when this function is called
       
  7705     // and all drawing should be avoided in such situation.
       
  7706     TBool okToDraw = EFalse;
       
  7707 
       
  7708     //iExtension->StartCascadeMenuDisappearTransition();
       
  7709     if ( iCascadeMenuPane->IsVisible() )
       
  7710         {
       
  7711         okToDraw = AknsUtils::SkinInstance() != NULL;
       
  7712 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  7713         MAknListBoxTfxInternal *transApi = CAknListLoader::TfxApiInternal( iExtension->iGc );
       
  7714         if ( transApi && okToDraw )
       
  7715             {
       
  7716             iCascadeMenuPane->SetFocus( EFalse, EDrawNow );
       
  7717             }
       
  7718 #endif
       
  7719         // Stop ongoing comp. transitions, this is mostly for fast clicking
       
  7720         // cases to make sure that no "scrap" is left behind.
       
  7721         GfxTransEffect::NotifyExternalState( ENotifyGlobalAbort );
       
  7722         // cascade menu "cancel" animation. This does not apply
       
  7723         // when something is chosen from the menu
       
  7724 
       
  7725     if( iExtension->iShowCascadeTransition && okToDraw )
       
  7726         {
       
  7727         iCascadeMenuPane->SetParent( this );
       
  7728 
       
  7729         GfxTransEffect::Begin( iCascadeMenuPane, KGfxControlDisappearAction );
       
  7730         GfxTransEffect::SetDemarcation( iCascadeMenuPane, iExtension->iCascadeDRect );
       
  7731 
       
  7732         iCascadeMenuPane->MakeVisible( EFalse );
       
  7733 
       
  7734         GfxTransEffect::End( iCascadeMenuPane );
       
  7735 
       
  7736             }
       
  7737         }
       
  7738 
       
  7739         // deregister right away since cascade menu is deleted
       
  7740     GfxTransEffect::Deregister( iCascadeMenuPane );
       
  7741     iExtension->iShowCascadeTransition = EFalse;
       
  7742 
       
  7743     //For transitions, keep the cascade menu object alive a little
       
  7744     // longer so that the transition system does not ever refer to
       
  7745     // deleted object
       
  7746     iExtension->iCascadeMenuObject = iCascadeMenuPane;
       
  7747 
       
  7748     
       
  7749     iCascadeMenuPane->MakeVisible( EFalse );
       
  7750     iCascadeMenuPane = NULL;
       
  7751 
       
  7752     if ( !aMainMenuClosing )
       
  7753         {
       
  7754         // Submenu is closed.Parent menu pane will grab window.
       
  7755         // ClaimPointerGrab invokes pointer up event.
       
  7756         ClaimPointerGrab(ETrue); 
       
  7757         }
       
  7758     }
       
  7759 
       
  7760 
       
  7761 // -----------------------------------------------------------------------------
       
  7762 // CEikMenuPane::NewItemCommandMenuL
       
  7763 // -----------------------------------------------------------------------------
       
  7764 //
       
  7765 CEikMenuPane* CEikMenuPane::NewItemCommandMenuL( MEikMenuObserver* aObserver )
       
  7766     {
       
  7767     CEikMenuPane* menuPane = new ( ELeave ) CEikMenuPane( aObserver );
       
  7768     CleanupStack::PushL( menuPane );
       
  7769     menuPane->iExtension = new ( ELeave ) CEikMenuPaneExtension();
       
  7770     menuPane->iExtension->iFlags.Set(
       
  7771             CEikMenuPaneExtension::ESingleClickEnabled );
       
  7772     menuPane->CreateItemArrayL();
       
  7773     CleanupStack::Pop( menuPane );
       
  7774     return menuPane;
       
  7775     }
       
  7776 
       
  7777 
       
  7778 // -----------------------------------------------------------------------------
       
  7779 // CEikMenuPane::SetItemCommandsDimmed
       
  7780 // -----------------------------------------------------------------------------
       
  7781 //
       
  7782 void CEikMenuPane::SetItemCommandsDimmed()
       
  7783     {
       
  7784     if ( iExtension && iExtension->iFlags.IsSet(
       
  7785             CEikMenuPaneExtension::ESingleClickEnabled ) )
       
  7786         {
       
  7787         iExtension->iFlags.Set(
       
  7788                 CEikMenuPaneExtension::EHideItemSpecificCommands );
       
  7789         for ( TInt i = 0; i < iItemArray->Count(); ++i )
       
  7790             {
       
  7791             CEikMenuPaneItem* item = iItemArray->At( i );
       
  7792             if ( item->iData.iFlags & EEikMenuItemAction
       
  7793                     || item->iData.iFlags & EEikMenuItemSpecific
       
  7794                     || item->iData.iFlags & EEikMenuItemSpecificListQuery )
       
  7795                 {
       
  7796                 item->iData.iFlags |= EEikMenuItemDimmed;
       
  7797                 }
       
  7798             }
       
  7799         }
       
  7800     }
       
  7801 
       
  7802 
       
  7803 // -----------------------------------------------------------------------------
       
  7804 // CEikMenuPane::AddMenuItemsToItemActionMenuL
       
  7805 // -----------------------------------------------------------------------------
       
  7806 //
       
  7807 void CEikMenuPane::AddMenuItemsToItemActionMenuL(
       
  7808         CAknItemActionMenuData& aMenuData )
       
  7809     {
       
  7810     TInt menuItemCount( iItemArray->Count() );
       
  7811     for ( TInt i = 0; i < menuItemCount; ++i )
       
  7812         {
       
  7813         CEikMenuPaneItem* item = iItemArray->At( i );
       
  7814         // Add menu item if menu item is not dimmed and
       
  7815         // 1) menu item belongs to cascade menu
       
  7816         // 2) menu item is item specific command
       
  7817         // 3) menu item is item specific list query
       
  7818         if ( CEikMenuPaneExtension::ItemSpecificCommand( *item ) )
       
  7819             {
       
  7820             // If menu item is not list query and it has cascade menu
       
  7821             // add cascade menu items to menu data directly
       
  7822             if ( !( item->iData.iFlags & EEikMenuItemSpecificListQuery )
       
  7823                     && item->iData.iCascadeId )
       
  7824                 {
       
  7825                 AddCascadeMenuItemsToActionMenuL(
       
  7826                         item->iData.iCascadeId, EFalse, aMenuData );
       
  7827                 }
       
  7828             // If menu item is list query or it does not have cascade menu
       
  7829             else
       
  7830                 {
       
  7831                 aMenuData.AddMenuItemToDataArrayL(
       
  7832                         item->iData.iCommandId,
       
  7833                         item->iData.iCascadeId,
       
  7834                         item->iData.iText );
       
  7835                 }
       
  7836             }
       
  7837         // If item is not item specific, add its item specific cascade menu
       
  7838         // items if the item itself isn't dimmed.
       
  7839         else if ( item->iData.iCascadeId && 
       
  7840                 !( item->iData.iFlags & EEikMenuItemDimmed ) )
       
  7841             {
       
  7842             AddCascadeMenuItemsToActionMenuL(
       
  7843                     item->iData.iCascadeId, ETrue, aMenuData );
       
  7844             }
       
  7845         }
       
  7846     }
       
  7847 
       
  7848 
       
  7849 // -----------------------------------------------------------------------------
       
  7850 // CEikMenuPane::AddCascadeMenuItemsToActionMenuL
       
  7851 // -----------------------------------------------------------------------------
       
  7852 //
       
  7853 void CEikMenuPane::AddCascadeMenuItemsToActionMenuL(
       
  7854         TInt aCascadeId,
       
  7855         TBool aItemSpecific,
       
  7856         CAknItemActionMenuData& aMenuData )
       
  7857     {
       
  7858     if ( aCascadeId && iCoeEnv->IsResourceAvailableL( aCascadeId ) )
       
  7859         {
       
  7860         CEikMenuPane* cascadeMenu =
       
  7861             CEikMenuPane::NewItemCommandMenuL( iMenuObserver );
       
  7862         CleanupStack::PushL( cascadeMenu );
       
  7863         cascadeMenu->AddMenuItemsL( aCascadeId, 0 );
       
  7864         iMenuObserver->DynInitMenuPaneL( aCascadeId, cascadeMenu );
       
  7865 
       
  7866         TInt menuItemCount( cascadeMenu->iItemArray->Count() );
       
  7867         for ( TInt i = 0; i < menuItemCount; ++i )
       
  7868             {
       
  7869             CEikMenuPaneItem* item = cascadeMenu->iItemArray->At( i );
       
  7870             if ( ( aItemSpecific
       
  7871                     && CEikMenuPaneExtension::ItemSpecificCommand( *item ) )
       
  7872                 || ( !aItemSpecific
       
  7873                         && !( item->iData.iFlags & EEikMenuItemDimmed ) ) )
       
  7874                 {
       
  7875                 aMenuData.AddMenuItemToDataArrayL(
       
  7876                         item->iData.iCommandId,
       
  7877                         item->iData.iCascadeId,
       
  7878                         item->iData.iText );
       
  7879                 }
       
  7880             }
       
  7881         CleanupStack::PopAndDestroy( cascadeMenu );
       
  7882         }
       
  7883     }
       
  7884 
       
  7885 
       
  7886 // -----------------------------------------------------------------------------
       
  7887 // CEikMenuPane::SetDefaultHighlight
       
  7888 // -----------------------------------------------------------------------------
       
  7889 //
       
  7890 void CEikMenuPane::SetDefaultHighlight()
       
  7891     {
       
  7892     if ( iExtension )
       
  7893         {
       
  7894         iExtension->SetDefaultHighlight();
       
  7895         }
       
  7896     }
       
  7897 
       
  7898 // end of file
       
  7899