uifw/EikStd/coctlsrc/aknstyluspopupmenucontent.cpp
changeset 0 2f259fa3e83a
child 4 8ca85d2f0db7
child 14 3320e4e6e8bb
equal deleted inserted replaced
-1:000000000000 0:2f259fa3e83a
       
     1 /*
       
     2 * Copyright (c) 2005-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:  Content that is shown inside a stylus popup menu.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <aknlayoutscalable_avkon.cdl.h>
       
    20 #include <AknsEffectAnim.h>
       
    21 #include <AknsDrawUtils.h>
       
    22 #include <AknsFrameBackgroundControlContext.h>
       
    23 #include <AknBidiTextUtils.h>
       
    24 #include <AknUtils.h>
       
    25 #include <AknsConstants.h>
       
    26 #include <eikapp.h>
       
    27 #include <aknappui.h>
       
    28 #include <AknDef.h>
       
    29 #include <touchfeedback.h>
       
    30 
       
    31 #include "aknstyluspopupmenuphysicshandler.h"
       
    32 #include "aknstyluspopupmenucontent.h"
       
    33 
       
    34 const TInt KItemArrayGranularity = 4;
       
    35 
       
    36 // Item shown or dimmed
       
    37 const TInt KShown = 0; 
       
    38 const TInt KHidden = 1; 
       
    39 
       
    40 const TInt KNoItemSelected = -1; 
       
    41 
       
    42 
       
    43 // =============================================================================
       
    44 // Item class declaration & definition
       
    45 // =============================================================================
       
    46 //
       
    47 NONSHARABLE_CLASS( CAknStylusPopUpMenuItem ) : public CBase
       
    48     {
       
    49     public:
       
    50         CAknStylusPopUpMenuItem( TInt aCommandId );
       
    51         ~CAknStylusPopUpMenuItem();
       
    52         void ConstructL(const TDesC& aText); 
       
    53     public: //Data
       
    54         TInt iCommandId; 
       
    55         TInt iVisibility;
       
    56         HBufC* iText;
       
    57         TRect iRect;   
       
    58     }; 
       
    59 
       
    60 // -----------------------------------------------------------------------------
       
    61 // CAknStylusPopUpMenuItem::CAknStylusPopUpMenuItem
       
    62 // Default constructor
       
    63 // -----------------------------------------------------------------------------
       
    64 //
       
    65 CAknStylusPopUpMenuItem::CAknStylusPopUpMenuItem( TInt aCommandId): 
       
    66     iCommandId( aCommandId ), iVisibility( KShown )
       
    67     {
       
    68     }
       
    69 
       
    70 // -----------------------------------------------------------------------------
       
    71 // CAknStylusPopUpMenuItem::CAknStylusPopUpMenuItem
       
    72 // Destructor
       
    73 // -----------------------------------------------------------------------------
       
    74 //
       
    75 CAknStylusPopUpMenuItem::~CAknStylusPopUpMenuItem()
       
    76     {
       
    77     delete iText; 
       
    78     }
       
    79 
       
    80 // -----------------------------------------------------------------------------
       
    81 // CAknStylusPopUpMenuItem::CAknStylusPopUpMenuItem
       
    82 // Default constructor
       
    83 // -----------------------------------------------------------------------------
       
    84 //
       
    85 void CAknStylusPopUpMenuItem::ConstructL(const TDesC& aText)
       
    86     {
       
    87     delete iText;
       
    88     iText = NULL; 
       
    89     iText = aText.AllocL(); 
       
    90     }
       
    91 
       
    92 
       
    93 
       
    94 // =============================================================================
       
    95 // Extension class declaration & definition
       
    96 // =============================================================================
       
    97 /*
       
    98  * Extension contains menu highlight animation functionality. 
       
    99  * The CAknStylusPopUpMenuContent class contains a pointer to 
       
   100  * this structure. 
       
   101  */
       
   102 
       
   103 NONSHARABLE_CLASS( CAknStylusPopUpMenuExtension ):
       
   104     public CActive,
       
   105     public MAknsEffectAnimObserver
       
   106     {
       
   107 public:
       
   108     enum TFlag
       
   109         {
       
   110         /**
       
   111         * If set, animation creation is attempted. If not set, animation will
       
   112         * never be created.
       
   113         */
       
   114         EFlagUseAnimation = 0
       
   115         };
       
   116 
       
   117     CAknStylusPopUpMenuExtension();
       
   118     ~CAknStylusPopUpMenuExtension();
       
   119 
       
   120     void ConstructL( CAknStylusPopUpMenuContent* aControl );
       
   121     TInt CreateAnimation();
       
   122     void HandleLayoutSwitch();
       
   123     void ChangeHighlightBackground();
       
   124     void MenuClosed();
       
   125 
       
   126 public: // Implementation of MAknsEffectAnimObserver
       
   127     void AnimFrameReady( TInt aError, TInt );
       
   128 
       
   129 protected: // CActive overloads
       
   130     void DoCancel();
       
   131     void RunL();
       
   132 
       
   133 private: // New internal methods
       
   134     void NoAnimIfError( TInt aError );
       
   135     void UseNoAnimation();
       
   136     void Play();
       
   137     TBool DrawHighlightBackground( CFbsBitGc& aGc );
       
   138     void PostDeleteAnimation();
       
   139     void CreateAnimationL( const TSize& aHighlightSize );
       
   140     void DoResizeL( const TSize& aHighlightSize, TBool aAboutToStart );
       
   141 
       
   142 public: // Data
       
   143     CAknsEffectAnim* iAnimation;
       
   144     /**
       
   145     * Stored flags are explained in enumeration TFlags.
       
   146     */
       
   147     TBitFlags32 iAnimFlags; 
       
   148     TBool iObserverInformed; 
       
   149     TBool iInformObserver; 
       
   150 private: //Data    
       
   151     CAknStylusPopUpMenuContent* iControl;
       
   152     };
       
   153 
       
   154 // -----------------------------------------------------------------------------
       
   155 // CAknStylusPopUpMenuExtension::CAknStylusPopUpMenuExtension
       
   156 // High CActive priority is well argumented because running the active object
       
   157 // will result in animation deletion -> results in freeing resources.
       
   158 // -----------------------------------------------------------------------------
       
   159 //
       
   160 CAknStylusPopUpMenuExtension::CAknStylusPopUpMenuExtension() :
       
   161     CActive( EPriorityHigh ),
       
   162     iAnimFlags ( 0 )
       
   163     {
       
   164     }
       
   165 
       
   166 // -----------------------------------------------------------------------------
       
   167 // CAknStylusPopUpMenuExtension::~CAknStylusPopUpMenuExtension
       
   168 // Destructor for extension class
       
   169 // -----------------------------------------------------------------------------
       
   170 //
       
   171 CAknStylusPopUpMenuExtension::~CAknStylusPopUpMenuExtension()
       
   172     {
       
   173     Cancel(); // Cancel possibly pending request
       
   174     delete iAnimation;
       
   175     }
       
   176 
       
   177 // -----------------------------------------------------------------------------
       
   178 // CAknStylusPopUpMenuExtension::ConstructL
       
   179 // -----------------------------------------------------------------------------
       
   180 //
       
   181 void CAknStylusPopUpMenuExtension::ConstructL( CAknStylusPopUpMenuContent* aControl )
       
   182     {
       
   183     ASSERT( aControl );
       
   184     iControl = aControl;
       
   185     iAnimFlags.Set( EFlagUseAnimation ); // Animations are created by default
       
   186     CActiveScheduler::Add( this );
       
   187     }
       
   188 
       
   189 // -----------------------------------------------------------------------------
       
   190 // CAknStylusPopUpMenuExtension::CreateAnimation
       
   191 // -----------------------------------------------------------------------------
       
   192 //
       
   193 TInt CAknStylusPopUpMenuExtension::CreateAnimation()
       
   194     {
       
   195     if( !iAnimation && iAnimFlags.IsSet( EFlagUseAnimation ) )
       
   196         {
       
   197         TRAPD( err, CreateAnimationL( iControl->HighlightRect().Size() ) );
       
   198         if( KErrNone != err )
       
   199             {
       
   200             // Animation has not been drawn -> no need for repaint
       
   201             UseNoAnimation();
       
   202             return err; 
       
   203             }
       
   204         }
       
   205     return KErrNone; 
       
   206     }
       
   207 
       
   208 // -----------------------------------------------------------------------------
       
   209 // CAknStylusPopUpMenuExtension::NoAnimIfError
       
   210 // -----------------------------------------------------------------------------
       
   211 //
       
   212 void CAknStylusPopUpMenuExtension::NoAnimIfError( TInt aError )
       
   213     {
       
   214     if( KErrNone != aError )
       
   215         {
       
   216         UseNoAnimation();
       
   217         }
       
   218     }
       
   219 
       
   220 // -----------------------------------------------------------------------------
       
   221 // CAknStylusPopUpMenuExtension::UseNoAnimation
       
   222 // Falls back to normal highlight rendering.
       
   223 // -----------------------------------------------------------------------------
       
   224 //
       
   225 void CAknStylusPopUpMenuExtension::UseNoAnimation()
       
   226     {
       
   227     delete iAnimation;
       
   228     iAnimation = NULL;
       
   229 
       
   230     // Do not attempt to create animations in the future
       
   231     iAnimFlags.Clear( EFlagUseAnimation );
       
   232     }
       
   233 
       
   234 
       
   235 // -----------------------------------------------------------------------------
       
   236 // CAknStylusPopUpMenuExtension::HandleLayoutSwitch
       
   237 // -----------------------------------------------------------------------------
       
   238 //
       
   239 void CAknStylusPopUpMenuExtension::HandleLayoutSwitch()
       
   240     {
       
   241     if( iAnimation ) // Animation exists -> try to resize
       
   242         {
       
   243         // Resize animation
       
   244         TBool aboutToStart = ETrue;
       
   245         if( iAnimation->State() == EAknsAnimStateStopped )
       
   246             {
       
   247             aboutToStart = EFalse;
       
   248             }
       
   249 
       
   250         TRAPD( err, DoResizeL( iControl->HighlightRect().Size(), aboutToStart ) );
       
   251         NoAnimIfError( err );
       
   252         }
       
   253     }
       
   254 
       
   255 // -----------------------------------------------------------------------------
       
   256 // CAknStylusPopUpMenuExtension::ChangeHighlightBackground
       
   257 // -----------------------------------------------------------------------------
       
   258 //
       
   259 void CAknStylusPopUpMenuExtension::ChangeHighlightBackground()
       
   260     {
       
   261     // Every time the current menu item is changed we need to change the
       
   262     // animation input layer (animated element is the highlight background that
       
   263     // can differ between highlight positions).
       
   264     if( iAnimation )
       
   265         {
       
   266         if( iAnimation->State() == EAknsAnimStateStopped  )
       
   267             {
       
   268             // Input layers don't exist when stopped or finished. We need to
       
   269             // resize to create the input layers and to update the output
       
   270             // layer.
       
   271             TRAPD( err, DoResizeL( iAnimation->Size(), EFalse ) );
       
   272             NoAnimIfError( err );
       
   273             }
       
   274         else // Either paused, running or finished
       
   275             {
       
   276             // Update the highlight background
       
   277             if( iAnimation->InputRgbGc() )
       
   278                 {
       
   279                 DrawHighlightBackground( *iAnimation->InputRgbGc() );
       
   280                 }
       
   281 
       
   282             // We need to update the output frame (otherwise the highlight
       
   283             // would be drawn with the old output before the next new animation
       
   284             // frame).
       
   285             NoAnimIfError( iAnimation->UpdateOutput() );
       
   286             }
       
   287         }
       
   288     }
       
   289 
       
   290 // -----------------------------------------------------------------------------
       
   291 // CAknStylusPopUpMenuExtension::MenuClosed
       
   292 // -----------------------------------------------------------------------------
       
   293 //
       
   294 void CAknStylusPopUpMenuExtension::MenuClosed()
       
   295     {
       
   296     delete iAnimation;
       
   297     iAnimation = NULL;
       
   298 
       
   299     iAnimFlags.Set( EFlagUseAnimation );
       
   300 
       
   301     }
       
   302 
       
   303 // -----------------------------------------------------------------------------
       
   304 // CAknStylusPopUpMenuExtension::AnimFrameReady
       
   305 // -----------------------------------------------------------------------------
       
   306 //
       
   307 void CAknStylusPopUpMenuExtension::AnimFrameReady( TInt aError, TInt )
       
   308     {
       
   309     if( KErrNone != aError )
       
   310         {
       
   311         // Animation has failed to run -> schedule the animation for
       
   312         // deletion to fall back to normal rendering.
       
   313         PostDeleteAnimation();
       
   314         }
       
   315     else if( iControl ) // Frame ok
       
   316         {
       
   317         if ( iControl->IsVisible() )
       
   318             {
       
   319             iControl->RepaintHighlight();
       
   320             }
       
   321         }
       
   322     }
       
   323 
       
   324 // -----------------------------------------------------------------------------
       
   325 // CAknStylusPopUpMenuExtension::DoCancel
       
   326 // -----------------------------------------------------------------------------
       
   327 //
       
   328 void CAknStylusPopUpMenuExtension::DoCancel()
       
   329     {
       
   330     // Required method, but not needed
       
   331     }
       
   332 
       
   333 
       
   334 // -----------------------------------------------------------------------------
       
   335 // CAknStylusPopUpMenuExtension::RunL
       
   336 // Postponed animation deletion is done here
       
   337 // -----------------------------------------------------------------------------
       
   338 //
       
   339 void CAknStylusPopUpMenuExtension::RunL()
       
   340     {
       
   341     UseNoAnimation();
       
   342     }
       
   343 
       
   344 // -----------------------------------------------------------------------------
       
   345 // CAknStylusPopUpMenuExtension::Play
       
   346 // -----------------------------------------------------------------------------
       
   347 //
       
   348 void CAknStylusPopUpMenuExtension::Play()
       
   349     {
       
   350     if( !iAnimation )
       
   351         {
       
   352         return;
       
   353         }
       
   354 
       
   355     // No need to start running/finished animation
       
   356     if( EAknsAnimStateRunning == iAnimation->State() ||
       
   357         EAknsAnimStateFinished == iAnimation->State() )
       
   358         {
       
   359         return;
       
   360         }
       
   361     if( EAknsAnimStatePaused == iAnimation->State() )
       
   362         {
       
   363         NoAnimIfError( iAnimation->Continue() );
       
   364         }
       
   365     else if( EAknsAnimStateStopped == iAnimation->State() )
       
   366         {
       
   367         if( iAnimation->NeedsInputLayer() )
       
   368             {
       
   369             TRAPD( err, DoResizeL( iAnimation->Size(), ETrue ) );
       
   370             NoAnimIfError( err );
       
   371 
       
   372             if( KErrNone != err )
       
   373                 return;
       
   374             }
       
   375 
       
   376         NoAnimIfError( iAnimation->Start() );
       
   377         }
       
   378     }
       
   379 
       
   380 // -----------------------------------------------------------------------------
       
   381 // CAknStylusPopUpMenuExtension::DrawHighlightBackground
       
   382 // Draws skinned highlight background to the provided graphics context.
       
   383 // -----------------------------------------------------------------------------
       
   384 //
       
   385 TBool CAknStylusPopUpMenuExtension::DrawHighlightBackground( CFbsBitGc& aGc )
       
   386     {
       
   387     // Draw the background under the current highlight. This simplified
       
   388     // drawing, we only grab a piece from the menu background bitmap.
       
   389     MAknsSkinInstance* skin = AknsUtils::SkinInstance();
       
   390     MAknsControlContext *cc = AknsDrawUtils::ControlContext( iControl );
       
   391 
       
   392     return AknsDrawUtils::DrawBackground( skin, cc, iControl, aGc, TPoint(0,0),
       
   393                                           iControl->HighlightRect(),
       
   394                                           KAknsDrawParamRGBOnly );
       
   395     }
       
   396 
       
   397 // -----------------------------------------------------------------------------
       
   398 // CAknStylusPopUpMenuExtension::PostDeleteAnimation
       
   399 // Schedules the animation for deletion by activating the extension itself.
       
   400 // Deletion is postponed because in many error/failure occasions the caller has
       
   401 // been animation and direct deletion is possibly not safe (because function
       
   402 // stack would return through the deleted object).
       
   403 // -----------------------------------------------------------------------------
       
   404 //
       
   405 void CAknStylusPopUpMenuExtension::PostDeleteAnimation()
       
   406     {
       
   407     TRequestStatus* status = &iStatus;
       
   408     User::RequestComplete( status, KErrNone );
       
   409     SetActive();
       
   410     }
       
   411 
       
   412 // -----------------------------------------------------------------------------
       
   413 // CAknStylusPopUpMenuExtension::CreateAnimationL
       
   414 // -----------------------------------------------------------------------------
       
   415 //
       
   416 void CAknStylusPopUpMenuExtension::CreateAnimationL( const TSize& aHighlightSize )
       
   417     {
       
   418     delete iAnimation;
       
   419     iAnimation = NULL;
       
   420 
       
   421     iAnimation = CAknsEffectAnim::NewL( this );
       
   422 
       
   423     if( !iAnimation->ConstructFromSkinL( KAknsIIDQsnAnimList ) ) 
       
   424         {
       
   425         // Animation for the ID was not found from the skin
       
   426         User::Leave( KErrNotFound );
       
   427         }
       
   428 
       
   429     DoResizeL( aHighlightSize, ETrue );
       
   430 
       
   431     Play();
       
   432     }
       
   433 
       
   434 // -----------------------------------------------------------------------------
       
   435 // CAknStylusPopUpMenuExtension::DoResizeL
       
   436 // -----------------------------------------------------------------------------
       
   437 //
       
   438 void CAknStylusPopUpMenuExtension::DoResizeL(
       
   439     const TSize& aHighlightSize, TBool aAboutToStart )
       
   440     {
       
   441     iAnimation->BeginConfigInputLayersL( aHighlightSize, aAboutToStart );
       
   442 
       
   443     if( iAnimation->InputRgbGc() )
       
   444         {
       
   445         DrawHighlightBackground( *iAnimation->InputRgbGc() );
       
   446         }
       
   447 
       
   448     iAnimation->EndConfigInputLayersL();
       
   449     }
       
   450 
       
   451 
       
   452 
       
   453 // ======== MEMBER FUNCTIONS ========
       
   454 
       
   455 // ---------------------------------------------------------------------------
       
   456 // Constructor
       
   457 // ---------------------------------------------------------------------------
       
   458 //
       
   459 CAknStylusPopUpMenuContent::CAknStylusPopUpMenuContent( CAknStylusPopUpMenu& aPopUpMenu ) : 
       
   460     iItems( KItemArrayGranularity ), 
       
   461     iCurrentItem( KNoItemSelected ),
       
   462     iFirstItem ( 0 ),
       
   463     iPopUpMenu( aPopUpMenu ),
       
   464     iPhysicsHandler( 0 )
       
   465     {
       
   466     }
       
   467 
       
   468 
       
   469 // ---------------------------------------------------------------------------
       
   470 // CAknStylusPopUpMenuContent::ConstructL
       
   471 // ---------------------------------------------------------------------------
       
   472 //
       
   473 void CAknStylusPopUpMenuContent::ConstructL()
       
   474     {
       
   475     if ( !iExtension )
       
   476         {
       
   477         iExtension = new (ELeave) CAknStylusPopUpMenuExtension;
       
   478         iExtension->ConstructL( this );
       
   479         }
       
   480         
       
   481    if ( !iPhysicsHandler )
       
   482         {
       
   483         iPhysicsHandler = CAknStylusPopUpMenuPhysicsHandler::NewL( this );
       
   484         }     
       
   485         
       
   486     ControlEnv()->AddForegroundObserverL( *this );
       
   487     MakeVisible( EFalse );
       
   488     }
       
   489 
       
   490 // ---------------------------------------------------------------------------
       
   491 // CAknStylusPopUpMenuContent::NewL
       
   492 // ---------------------------------------------------------------------------
       
   493 //
       
   494 CAknStylusPopUpMenuContent* CAknStylusPopUpMenuContent::NewL( CAknStylusPopUpMenu& aPopUpMenu )
       
   495     {
       
   496     CAknStylusPopUpMenuContent* self = CAknStylusPopUpMenuContent::NewLC( aPopUpMenu );
       
   497     CleanupStack::Pop( self );
       
   498     return self;
       
   499     }
       
   500 
       
   501 
       
   502 // ---------------------------------------------------------------------------
       
   503 // CAknStylusPopUpMenuContent::NewLC
       
   504 // ---------------------------------------------------------------------------
       
   505 //
       
   506 CAknStylusPopUpMenuContent* CAknStylusPopUpMenuContent::NewLC( CAknStylusPopUpMenu& aPopUpMenu )
       
   507     {
       
   508     CAknStylusPopUpMenuContent* self = new ( ELeave ) CAknStylusPopUpMenuContent( aPopUpMenu );
       
   509     CleanupStack::PushL( self );
       
   510     self->ConstructL();
       
   511     return self;
       
   512     }
       
   513 
       
   514 
       
   515 // ---------------------------------------------------------------------------
       
   516 // Destructor
       
   517 // ---------------------------------------------------------------------------
       
   518 //
       
   519 CAknStylusPopUpMenuContent::~CAknStylusPopUpMenuContent()
       
   520     {
       
   521     delete iPhysicsHandler;
       
   522     
       
   523     iItems.ResetAndDestroy();
       
   524     CCoeEnv::Static()->RemoveForegroundObserver( *this );
       
   525     delete iExtension; 
       
   526     if ( iSBFrame )
       
   527         {
       
   528         delete iSBFrame;    
       
   529         }
       
   530     }
       
   531 
       
   532 
       
   533 // ---------------------------------------------------------------------------
       
   534 // Adds a new menu item to the array of items.
       
   535 // ---------------------------------------------------------------------------
       
   536 //
       
   537 void CAknStylusPopUpMenuContent::AddMenuItemL( const TDesC& aItem, 
       
   538     const TInt aCommandId )
       
   539     {
       
   540     __ASSERT_DEBUG( !IsVisible(), User::Invariant() ); 
       
   541 
       
   542     CAknStylusPopUpMenuItem* item = new (ELeave) CAknStylusPopUpMenuItem( 
       
   543         aCommandId );
       
   544     CleanupStack::PushL( item ); 
       
   545     item->ConstructL( aItem );  
       
   546     iItems.AppendL( item );
       
   547     CleanupStack::Pop( item ); 
       
   548 
       
   549     }
       
   550 
       
   551 // ---------------------------------------------------------------------------
       
   552 // Removes the menu item based on the given command id and frees the 
       
   553 // memory occupied by it.
       
   554 // ---------------------------------------------------------------------------
       
   555 //
       
   556 void CAknStylusPopUpMenuContent::RemoveMenuItem( const TInt aCommandId )
       
   557     {
       
   558     __ASSERT_DEBUG( !IsVisible(), User::Invariant() ); 
       
   559     TBool changed = EFalse;
       
   560     for ( TInt itemIndex = iItems.Count() - 1; itemIndex >= 0; itemIndex-- )
       
   561         {
       
   562         if ( iItems[itemIndex]->iCommandId == aCommandId )
       
   563             {
       
   564             delete iItems[itemIndex];
       
   565             iItems.Remove( itemIndex );
       
   566             if ( iFirstItem > itemIndex && iFirstItem > 0 )
       
   567                 {
       
   568                 iFirstItem--;
       
   569                 }
       
   570             changed = ETrue;
       
   571             }
       
   572         }
       
   573     if ( changed )
       
   574         {
       
   575         SizeChanged();
       
   576         }
       
   577     }
       
   578 
       
   579 // ---------------------------------------------------------------------------
       
   580 // Hides / unhides the menu item based on the given command id 
       
   581 // ---------------------------------------------------------------------------
       
   582 //
       
   583 void CAknStylusPopUpMenuContent::SetItemDimmed( const TInt aCommandId, const TBool aDimmed )
       
   584     {
       
   585     __ASSERT_DEBUG( !IsVisible(), User::Invariant() ); 
       
   586     
       
   587     TInt itemIndex( 0 );
       
   588     TBool sizeChanged( EFalse );
       
   589     TInt newVisibility( KShown );
       
   590     
       
   591     if ( aDimmed )
       
   592         {
       
   593         newVisibility = KHidden;
       
   594         }
       
   595     
       
   596     // Set new visibility to item if it has changed
       
   597     for ( itemIndex = 0; itemIndex < iItems.Count(); itemIndex++ )
       
   598         {
       
   599         if ( iItems[itemIndex]->iCommandId == aCommandId )
       
   600             {
       
   601             if ( iItems[itemIndex]->iVisibility != newVisibility )
       
   602                 {
       
   603                 iItems[itemIndex]->iVisibility = newVisibility;
       
   604                 sizeChanged = ETrue;
       
   605                 }
       
   606             break; 
       
   607             }
       
   608         }
       
   609 
       
   610     // Update first item and popup size if necessary
       
   611     if ( sizeChanged )
       
   612         {
       
   613         if ( iFirstItem >= itemIndex && iFirstItem > 0 )
       
   614             {
       
   615             for ( TInt i = 0; i < iItems.Count(); i++ )
       
   616                 {
       
   617                 if ( iItems[i]->iVisibility == KShown )
       
   618                     {
       
   619                     iFirstItem = i;
       
   620                     break;
       
   621                     }
       
   622                 }
       
   623             }
       
   624         //SizeChanged();
       
   625         }
       
   626     }
       
   627 
       
   628 // ---------------------------------------------------------------------------
       
   629 // Returns the command id of the specified menu item.
       
   630 // ---------------------------------------------------------------------------
       
   631 //
       
   632 TInt CAknStylusPopUpMenuContent::CurrentCommandId() const
       
   633     {
       
   634     if ( iCurrentItem >= 0 && iCurrentItem < iItems.Count() )
       
   635         {
       
   636         return iItems[iCurrentItem]->iCommandId; 
       
   637         }
       
   638     return KErrNotFound; 
       
   639     }
       
   640         
       
   641 
       
   642 // -----------------------------------------------------------------------------
       
   643 // CAknStylusPopUpMenuContent::RepaintHighlight
       
   644 // -----------------------------------------------------------------------------
       
   645 //
       
   646 void CAknStylusPopUpMenuContent::RepaintHighlight() const
       
   647     {
       
   648     ActivateGc();
       
   649     CWindowGc& gc = SystemGc();
       
   650     Window().Invalidate( HighlightRect() ); 
       
   651     Window().BeginRedraw( HighlightRect() ); 
       
   652     DrawItem( gc, iCurrentItem, EDrawHighlight );
       
   653     Window().EndRedraw(); 
       
   654     DeactivateGc();
       
   655     }
       
   656 
       
   657 
       
   658 // -----------------------------------------------------------------------------
       
   659 // CAknStylusPopUpMenuContent::HighlightRect
       
   660 // -----------------------------------------------------------------------------
       
   661 //
       
   662 TRect CAknStylusPopUpMenuContent::HighlightRect() const
       
   663     {
       
   664     if ( iCurrentItem >= 0 && iCurrentItem < iItems.Count() )
       
   665         {
       
   666         return iItems[iCurrentItem]->iRect; 
       
   667         }
       
   668     return TRect(); 
       
   669     }
       
   670 
       
   671 
       
   672 // -----------------------------------------------------------------------------
       
   673 // CAknStylusPopUpMenuContent::Clear
       
   674 // -----------------------------------------------------------------------------
       
   675 //
       
   676 void CAknStylusPopUpMenuContent::Clear()
       
   677     {
       
   678     iItems.ResetAndDestroy();
       
   679     iCurrentItem = KNoItemSelected;
       
   680     iFirstItem = 0;
       
   681     iPhysicsHandler->Reset();
       
   682     }
       
   683 
       
   684 
       
   685 // ---------------------------------------------------------------------------
       
   686 // From class CCoeControl
       
   687 // Calculates the total size needed to display the items.
       
   688 // ---------------------------------------------------------------------------
       
   689 //
       
   690 TSize CAknStylusPopUpMenuContent::MinimumSize()
       
   691     {
       
   692     TInt textWidth = 0; // Text width 
       
   693     TInt height = 0; // height of all menu items combined.
       
   694     TInt width = 0; // Width of menu
       
   695     TInt visibleItems = 0; // Number of visible items
       
   696     
       
   697     // Find the widest visible item and count visible items
       
   698     for ( TInt i = 0; i < iItems.Count(); i++ )
       
   699         {
       
   700         if ( iItems[i]->iVisibility == KShown )
       
   701             {
       
   702             visibleItems++;
       
   703             textWidth = AknLayoutUtils::FontFromId( AknLayoutScalable_Avkon::
       
   704             list_single_popup_submenu_pane_t1( 0 ).LayoutLine().FontId() )->TextWidthInPixels( *( iItems[i]->iText ) );
       
   705             width = Max( width, textWidth );
       
   706             }
       
   707         }
       
   708         
       
   709     if ( visibleItems == 0 )
       
   710         {
       
   711         return TSize( 0, 0 );
       
   712         }
       
   713             
       
   714     TRect mainPaneRect;
       
   715     AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EMainPane,
       
   716                                        mainPaneRect );
       
   717     TAknWindowLineLayout listLayout = 
       
   718        AknLayoutScalable_Avkon::list_single_touch_menu_pane(0).LayoutLine();
       
   719  
       
   720     TAknTextLineLayout textLayout = 
       
   721        AknLayoutScalable_Avkon::list_single_touch_menu_pane_t1().LayoutLine();
       
   722 
       
   723     TAknWindowLineLayout unit = 
       
   724        AknLayoutScalable_Avkon::aid_value_unit2().LayoutLine();
       
   725     
       
   726     TInt singleItemHeight = listLayout.iH; 
       
   727     height = singleItemHeight * visibleItems;
       
   728     
       
   729     if ( height > mainPaneRect.Height() )
       
   730         {
       
   731         TInt fitsToMenu = mainPaneRect.Height() / singleItemHeight;
       
   732         height = fitsToMenu * singleItemHeight;
       
   733         TAknWindowLineLayout scrollBar = 
       
   734             AknLayoutScalable_Avkon::scroll_pane( 0 );
       
   735         width += scrollBar.iW;
       
   736         }
       
   737 
       
   738     width += textLayout.ir + textLayout.il;
       
   739 
       
   740     if ( width > ( mainPaneRect.Width() - unit.iW ) )
       
   741         {
       
   742         width = mainPaneRect.Width() - ( unit.iW );
       
   743         }
       
   744 
       
   745     return TSize( width, height );
       
   746     }
       
   747 
       
   748 // ---------------------------------------------------------------------------
       
   749 // From class CCoeControl
       
   750 // CAknStylusPopUpMenuContent::HandleResourceChange
       
   751 // ---------------------------------------------------------------------------
       
   752 //    
       
   753 void CAknStylusPopUpMenuContent::HandleResourceChange( TInt aType )
       
   754     {
       
   755     CCoeControl::HandleResourceChange( aType );
       
   756     
       
   757     if ( aType == KAknsMessageSkinChange )
       
   758         {
       
   759         // Implementation when graphics are ready.
       
   760         }
       
   761     else if ( aType == KEikMessageFadeAllWindows 
       
   762               || aType == KEikDynamicLayoutVariantSwitch ) 
       
   763         {
       
   764         if ( Observer() ) 
       
   765             {
       
   766             // this will close the stylus popup menu
       
   767             TRAP_IGNORE( Observer()->HandleControlEventL( this,
       
   768                 MCoeControlObserver::EEventRequestExit ) );
       
   769             }    
       
   770         }            
       
   771     }
       
   772 
       
   773 // -----------------------------------------------------------------------------
       
   774 // CAknStylusPopUpMenuContent::HandlePointerEventL
       
   775 // -----------------------------------------------------------------------------
       
   776 //
       
   777 void CAknStylusPopUpMenuContent::HandlePointerEventL( 
       
   778         const TPointerEvent& aPointerEvent )
       
   779     {
       
   780     CAknControl::HandlePointerEventL( aPointerEvent );
       
   781     CCoeControl* grabber = GrabbingComponent();    
       
   782     if( grabber )
       
   783         {
       
   784         return;
       
   785         }
       
   786     iPhysicsHandler->HandlePointerEventL( aPointerEvent );
       
   787     }
       
   788 
       
   789 // -----------------------------------------------------------------------------
       
   790 // CAknStylusPopUpMenuContent::MakeVisible
       
   791 // -----------------------------------------------------------------------------
       
   792 //    
       
   793 void CAknStylusPopUpMenuContent::MakeVisible( TBool aVisible ) 
       
   794     {
       
   795     //Start highlight animation
       
   796     CAknControl::MakeVisible( aVisible);     
       
   797 
       
   798     if ( aVisible )
       
   799         {
       
   800         iCurrentItem = KNoItemSelected; 
       
   801         if ( iExtension )
       
   802             {
       
   803             iExtension->iInformObserver = ETrue; 
       
   804             iExtension->iObserverInformed = EFalse; 
       
   805             }
       
   806         // Fix for TSW Error EAJA-73MHSP
       
   807         ClaimPointerGrab( ETrue );
       
   808         UpdateScrollBar();
       
   809         
       
   810         // clear pressed down highlight from scrollbar
       
   811         if ( iSBFrame )
       
   812             {
       
   813             CAknDoubleSpanScrollBar* scrollbar = 
       
   814                 static_cast<CAknDoubleSpanScrollBar*>( 
       
   815                         iSBFrame->VerticalScrollBar() );
       
   816                 
       
   817             if ( scrollbar )
       
   818                 {
       
   819                 scrollbar->ResetPressedDownHighlight();
       
   820                 }
       
   821             }
       
   822         }
       
   823     else
       
   824         {
       
   825         if ( iExtension && iExtension->iInformObserver && !iExtension->iObserverInformed )
       
   826             {
       
   827             iExtension->iInformObserver = EFalse; 
       
   828             TRAP_IGNORE(Observer()->HandleControlEventL( this,
       
   829                 MCoeControlObserver::EEventRequestCancel )); 
       
   830             }
       
   831         if ( iSBFrame )
       
   832             {
       
   833             delete iSBFrame;
       
   834             iSBFrame = NULL;
       
   835             }
       
   836         if( iExtension )
       
   837             {
       
   838             iExtension->MenuClosed();    
       
   839             }
       
   840         }
       
   841     }
       
   842     
       
   843 // -----------------------------------------------------------------------------
       
   844 // CAknStylusPopUpMenuContent::CountComponentControls
       
   845 // -----------------------------------------------------------------------------
       
   846 //    
       
   847 TInt CAknStylusPopUpMenuContent::CountComponentControls() const
       
   848     {
       
   849     if ( iSBFrame )
       
   850         {
       
   851         return 1;
       
   852         }
       
   853     return 0;
       
   854     }
       
   855     
       
   856 // -----------------------------------------------------------------------------
       
   857 // CAknStylusPopUpMenuContent::ComponentControl
       
   858 // -----------------------------------------------------------------------------
       
   859 //    
       
   860 CCoeControl* CAknStylusPopUpMenuContent::ComponentControl( TInt aIndex ) const
       
   861     {
       
   862     return iSBFrame->ComponentControl( aIndex );
       
   863     }
       
   864 
       
   865 // -----------------------------------------------------------------------------
       
   866 // CAknStylusPopUpMenuContent::MoveHighlightTo
       
   867 // Moves the menu pane highlight to the new selected menu item aNewSelectedItem.
       
   868 // -----------------------------------------------------------------------------
       
   869 //
       
   870 void CAknStylusPopUpMenuContent::MoveHighlightTo(TInt aNewSelectedItem)
       
   871     {
       
   872     TInt previous = KNoItemSelected; 
       
   873     if ( iCurrentItem == aNewSelectedItem )
       
   874         {
       
   875         return; 
       
   876         }
       
   877     else
       
   878         {
       
   879         previous = iCurrentItem; 
       
   880         iCurrentItem = aNewSelectedItem; 
       
   881         }
       
   882 
       
   883     ActivateGc(); 
       
   884     CWindowGc& gc =  SystemGc();
       
   885     if ( previous >= 0 && previous < iItems.Count() )
       
   886         {
       
   887         Window().Invalidate( iItems[previous]->iRect ); 
       
   888         Window().BeginRedraw( iItems[previous]->iRect ); 
       
   889         // Remove highlight from previously highlighted item
       
   890         DrawItem( gc, previous, ERemoveHighlight ); 
       
   891         Window().EndRedraw(); 
       
   892         }
       
   893     
       
   894     if( iExtension )
       
   895         {
       
   896         iExtension->ChangeHighlightBackground();
       
   897         }
       
   898     Window().Invalidate( HighlightRect() ); 
       
   899     Window().BeginRedraw( HighlightRect() );     
       
   900     DrawItem( gc, iCurrentItem, EDrawHighlight ); 
       
   901     Window().EndRedraw(); 
       
   902     DeactivateGc(); 
       
   903     }
       
   904 
       
   905 
       
   906 // -----------------------------------------------------------------------------
       
   907 // CAknStylusPopUpMenuContent::DrawItem
       
   908 // -----------------------------------------------------------------------------
       
   909 //
       
   910 void CAknStylusPopUpMenuContent::DrawItem(
       
   911     CWindowGc& aGc,TInt aItem,THighlightType aHighlight) const
       
   912     {
       
   913     TRect rect( iItems[aItem]->iRect );
       
   914     
       
   915     // Use offset to move items smoothly.
       
   916     // If physics not in use, offset is always 0.
       
   917     rect.Move( TPoint( 0, -Offset() ) ); 
       
   918 
       
   919     if ( aHighlight == EDrawHighlight )
       
   920         {
       
   921         TBool drawOk = EFalse; 
       
   922         if( iExtension->iAnimation ) // Draw animated highlight
       
   923             {
       
   924             drawOk = iExtension->iAnimation->Render( aGc, rect );
       
   925             }
       
   926         if ( !drawOk )
       
   927             {
       
   928             // Animated highlight was not available, use normal skinned
       
   929             // rendering.
       
   930             TAknLayoutRect listRect; 
       
   931             TAknLayoutRect innerRect;
       
   932 
       
   933             listRect.LayoutRect( rect, 
       
   934                 AknLayoutScalable_Avkon::list_highlight_pane_cp1().LayoutLine() );
       
   935             innerRect.LayoutRect( listRect.Rect(),
       
   936                 AknLayoutScalable_Avkon::list_highlight_pane_g1_cp1().LayoutLine() );
       
   937             
       
   938             MAknsSkinInstance* skin = AknsUtils::SkinInstance();
       
   939             aGc.SetBrushStyle( CGraphicsContext::ESolidBrush ); 
       
   940             // if we have transparent highlight, draw also background under highlight
       
   941             if ( Background() )
       
   942                 {
       
   943                 Background()->Draw( aGc, *this, rect );
       
   944                 }
       
   945             
       
   946             drawOk = AknsDrawUtils::DrawFrame( skin, aGc, rect, innerRect.Rect(), 
       
   947                 KAknsIIDQsnFrList, KAknsIIDDefault );
       
   948 
       
   949             //Both highlight animation and frame drawing failed. 
       
   950             if ( !drawOk )
       
   951                 {
       
   952                 listRect.DrawRect( aGc ); 
       
   953                 innerRect.DrawRect( aGc ); 
       
   954                 }
       
   955             }
       
   956         }
       
   957 
       
   958     if ( aHighlight == ERemoveHighlight && Background() )
       
   959         {
       
   960         Background()->Draw( aGc, *this, rect );
       
   961         }
       
   962 
       
   963     TAknLayoutText layoutText; 
       
   964     layoutText.LayoutText( rect, 
       
   965         AknLayoutScalable_Avkon::list_single_touch_menu_pane_t1().LayoutLine()); 
       
   966 
       
   967     MAknsSkinInstance* skin = AknsUtils::SkinInstance();
       
   968 
       
   969     TRgb textColor(layoutText.Color()); 
       
   970     AknsUtils::GetCachedColor( skin, textColor, KAknsIIDQsnTextColors,
       
   971                                    EAknsCIQsnTextColorsCG20 );
       
   972 
       
   973     layoutText.DrawText( aGc, *(iItems[aItem]->iText), ETrue, textColor ); 
       
   974     }
       
   975 
       
   976 // -----------------------------------------------------------------------------
       
   977 // CAknStylusPopUpMenuContent::StartAnimation
       
   978 // -----------------------------------------------------------------------------
       
   979 //
       
   980 TInt CAknStylusPopUpMenuContent::StartAnimation()
       
   981     {
       
   982     if( iExtension )
       
   983         {
       
   984         // Creates animation only if it does not exist
       
   985         return iExtension->CreateAnimation();
       
   986         }
       
   987     return KErrNotSupported; 
       
   988     }
       
   989 
       
   990 // -----------------------------------------------------------------------------
       
   991 // CAknStylusPopUpMenuContent::UpdateScrollBar
       
   992 // -----------------------------------------------------------------------------
       
   993 //
       
   994 void CAknStylusPopUpMenuContent::UpdateScrollBar()
       
   995     {
       
   996     if ( !iSBFrame )
       
   997         {
       
   998         return;
       
   999         }
       
  1000             
       
  1001     TAknWindowLineLayout listLayout = 
       
  1002     AknLayoutScalable_Avkon::list_single_touch_menu_pane(0).LayoutLine();
       
  1003 
       
  1004     TInt singleItemHeight = listLayout.iH; 
       
  1005     TRect listRect = Rect(); 
       
  1006     
       
  1007     TInt fitsToMenu = listRect.Height() / singleItemHeight;
       
  1008     TInt visibleItems = 0;
       
  1009     TInt thumbPos = 0;
       
  1010     
       
  1011     // Count visible items
       
  1012     for ( TInt i = 0; i < iItems.Count(); i++ )
       
  1013         {
       
  1014         if ( iItems[i]->iVisibility == KShown )
       
  1015             {
       
  1016             visibleItems++;
       
  1017             }
       
  1018         if ( i == iFirstItem )
       
  1019                 {
       
  1020                 thumbPos = visibleItems-1;
       
  1021                 }
       
  1022         }
       
  1023 
       
  1024     if ( fitsToMenu == 0 || visibleItems == 0 )
       
  1025         {
       
  1026         return;
       
  1027         }
       
  1028         
       
  1029     if ( visibleItems > fitsToMenu )
       
  1030         {
       
  1031         TRAP_IGNORE( iSBFrame->SetScrollBarVisibilityL(
       
  1032                                 CEikScrollBarFrame::EOff,
       
  1033                                 CEikScrollBarFrame::EOn ) );
       
  1034         }
       
  1035     else
       
  1036         {
       
  1037         TRAP_IGNORE( iSBFrame->SetScrollBarVisibilityL(
       
  1038                                 CEikScrollBarFrame::EOff,
       
  1039                                 CEikScrollBarFrame::EOff ) );
       
  1040         return;
       
  1041         }
       
  1042         
       
  1043     TAknDoubleSpanScrollBarModel vsbarModel;
       
  1044     TAknDoubleSpanScrollBarModel hsbarModel;
       
  1045     
       
  1046     if ( iSBFrame->VScrollBarVisibility() != CEikScrollBarFrame::EOff )
       
  1047         {
       
  1048         vsbarModel.iThumbPosition = thumbPos * singleItemHeight + Offset();
       
  1049         vsbarModel.iScrollSpan = visibleItems * singleItemHeight;
       
  1050         vsbarModel.iThumbSpan = fitsToMenu * singleItemHeight;
       
  1051             
       
  1052         TEikScrollBarFrameLayout layout;
       
  1053         layout.iTilingMode=TEikScrollBarFrameLayout::EInclusiveRectConstant;
       
  1054         layout.SetClientMargin(0);
       
  1055         layout.SetInclusiveMargin(0);
       
  1056         
       
  1057         TBool changed ( EFalse );
       
  1058         TRect clientRect( listRect );
       
  1059         TRect inclusiveRect( listRect );
       
  1060         TRAP_IGNORE ( changed = iSBFrame->TileL( &hsbarModel, 
       
  1061                                                  &vsbarModel,
       
  1062                                                  clientRect, 
       
  1063                                                  inclusiveRect, 
       
  1064                                                  layout ) );
       
  1065         if ( changed )
       
  1066             {
       
  1067             iSBFrame->DrawScrollBarsDeferred();
       
  1068             }
       
  1069         }
       
  1070     }
       
  1071 
       
  1072 // -----------------------------------------------------------------------------
       
  1073 // CAknStylusPopUpMenuContent::CalculateShownItems
       
  1074 // -----------------------------------------------------------------------------
       
  1075 //   
       
  1076 TInt CAknStylusPopUpMenuContent::CalculateShownItems(  TScrollType aScroll )
       
  1077     {
       
  1078     TInt visibleItems ( 0 );
       
  1079     TInt shownItems ( 0 );
       
  1080     TInt firstItem ( KNoItemSelected );
       
  1081     TInt lastItem ( 0 );
       
  1082     TRect listRect = Rect();
       
  1083 
       
  1084     //
       
  1085     // Empty listRect causes infinite loop in this
       
  1086     // function. (while ( lastItem == 0 || visibleItems < shownItems ))
       
  1087     //
       
  1088     // listRect can be empty if the popup menu is created
       
  1089     // from resource and RemoveMenuItem is called before
       
  1090     // making the popup menu visible.
       
  1091     //
       
  1092     TAknWindowLineLayout listLayout = 
       
  1093     AknLayoutScalable_Avkon::list_single_touch_menu_pane(0).LayoutLine();
       
  1094 
       
  1095     TInt singleItemHeight = listLayout.iH; 
       
  1096     TInt fitsToMenu = listRect.Height() / singleItemHeight;
       
  1097 
       
  1098     if ( iItems.Count() == 0 || listRect.IsEmpty() || fitsToMenu <= 0 )
       
  1099         {
       
  1100         return KNoItemSelected;
       
  1101         }
       
  1102    
       
  1103     // Count visible items and calculate first and last shown item
       
  1104     for ( TInt i = 0; i < iItems.Count(); i++ )
       
  1105         {
       
  1106         if ( iItems[i]->iVisibility == KShown )
       
  1107             {
       
  1108             if ( firstItem == KNoItemSelected )
       
  1109                 {
       
  1110                 firstItem = i;
       
  1111                 }
       
  1112             visibleItems++;
       
  1113             if ( i >= iFirstItem )
       
  1114                 {
       
  1115                 shownItems++;
       
  1116                 if ( shownItems == fitsToMenu )
       
  1117                     {
       
  1118                     lastItem = i;
       
  1119                     }
       
  1120                 }
       
  1121             }
       
  1122         }
       
  1123 
       
  1124     if ( visibleItems == 0 )
       
  1125         {
       
  1126         return KNoItemSelected;
       
  1127         }
       
  1128     
       
  1129     // Scrolling fixes to iFirstItem
       
  1130     if ( aScroll == EScrollUp && 
       
  1131          iItems[iFirstItem]->iVisibility == KHidden )
       
  1132         {
       
  1133         while ( iItems[iFirstItem]->iVisibility == KHidden && 
       
  1134                 iFirstItem > 0 )
       
  1135             {
       
  1136             iFirstItem--;
       
  1137             }
       
  1138         }
       
  1139 
       
  1140     if ( aScroll == EScrollDown && 
       
  1141          iItems[iFirstItem]->iVisibility == KHidden )
       
  1142         {
       
  1143         while ( iItems[iFirstItem]->iVisibility == KHidden &&
       
  1144                 iFirstItem < iItems.Count() - 1 )
       
  1145             {
       
  1146             iFirstItem++;
       
  1147             }
       
  1148         }
       
  1149         
       
  1150     // Is scroll bar needed
       
  1151     if ( visibleItems > fitsToMenu )
       
  1152         {
       
  1153         if ( !iSBFrame )
       
  1154             {
       
  1155             TRAPD( err, iSBFrame =  new ( ELeave ) CEikScrollBarFrame( 
       
  1156                     this, this, EFalse, ETrue ) );
       
  1157 
       
  1158             if ( !err )
       
  1159                 {
       
  1160                 TRAPD( err, iSBFrame->CreateDoubleSpanScrollBarsL( 
       
  1161                     EFalse, EFalse, ETrue, EFalse ) );
       
  1162 
       
  1163                 if ( !err )
       
  1164                     {
       
  1165                     iSBFrame->DrawBackground( EFalse, EFalse );
       
  1166                     if ( AknLayoutUtils::LayoutMirrored() )
       
  1167         	            {
       
  1168                         listRect.iTl.iX += AknLayoutScalable_Avkon::scroll_pane().LayoutLine().iW;
       
  1169         	            }
       
  1170                     else
       
  1171         	            {
       
  1172                         listRect.iBr.iX -= AknLayoutScalable_Avkon::scroll_pane().LayoutLine().iW;
       
  1173                         }
       
  1174                     }
       
  1175                 }
       
  1176             }
       
  1177         else
       
  1178         	{
       
  1179             if ( AknLayoutUtils::LayoutMirrored() )
       
  1180 	            {
       
  1181                 listRect.iTl.iX += AknLayoutScalable_Avkon::scroll_pane().LayoutLine().iW;
       
  1182 	            }
       
  1183             else
       
  1184 	            {
       
  1185                 listRect.iBr.iX -= AknLayoutScalable_Avkon::scroll_pane().LayoutLine().iW;
       
  1186                 }        	
       
  1187         	}
       
  1188 
       
  1189         }
       
  1190     
       
  1191     // Adjust first and last item 
       
  1192     if ( iFirstItem < firstItem )
       
  1193         {
       
  1194         iFirstItem = firstItem;
       
  1195         }
       
  1196     
       
  1197     if ( lastItem == 0 && ( visibleItems == 1 || fitsToMenu == 1 ) )
       
  1198         {
       
  1199         iFirstItem = firstItem;
       
  1200         lastItem = iFirstItem;
       
  1201         }
       
  1202     else
       
  1203         {
       
  1204         while ( lastItem == 0 || visibleItems < shownItems )
       
  1205             {
       
  1206             if ( iFirstItem > 0 )
       
  1207                 {
       
  1208                 iFirstItem--;    
       
  1209                 }
       
  1210             shownItems = 0;
       
  1211             // Count new last item
       
  1212             for ( TInt i = iFirstItem; i < iItems.Count(); i++ )
       
  1213                 {
       
  1214                 if ( iItems[i]->iVisibility == KShown )
       
  1215                     {
       
  1216                     shownItems++;
       
  1217                     if ( shownItems <= fitsToMenu  )
       
  1218                         {
       
  1219                         lastItem = i;
       
  1220                         }
       
  1221                     }
       
  1222                 }
       
  1223             }
       
  1224         }
       
  1225 
       
  1226     // add one item because to take partial items into account
       
  1227     ++lastItem;
       
  1228     
       
  1229     // Position items starting from the topmost item
       
  1230     for ( TInt i = 0; i < iItems.Count(); i ++ )
       
  1231         {
       
  1232         TRect itemRect;
       
  1233         if ( iItems[i]->iVisibility == KShown 
       
  1234              && ( i >= iFirstItem && i <= lastItem ) )
       
  1235             {
       
  1236             itemRect.SetRect ( listRect.iTl, 
       
  1237                                TSize( listRect.Width(), 
       
  1238                                singleItemHeight ) );
       
  1239             listRect.iTl.iY += singleItemHeight;
       
  1240             }
       
  1241          else
       
  1242             {
       
  1243             itemRect.SetRect( TPoint( 0,0 ), TPoint( 0,0 ) );
       
  1244             }
       
  1245         iItems[i]->iRect = itemRect;
       
  1246         }
       
  1247 
       
  1248     return lastItem;    
       
  1249     }
       
  1250 
       
  1251 // ---------------------------------------------------------------------------
       
  1252 // From class CCoeControl
       
  1253 // CAknStylusPopUpMenuContent::SizeChanged
       
  1254 // ---------------------------------------------------------------------------
       
  1255 //
       
  1256 void CAknStylusPopUpMenuContent::SizeChanged()
       
  1257     {
       
  1258     TAknWindowLineLayout listLayout = 
       
  1259         AknLayoutScalable_Avkon::list_single_touch_menu_pane(0).LayoutLine();
       
  1260 
       
  1261     iPhysicsHandler->SetItemHeight( listLayout.iH );
       
  1262     iPhysicsHandler->SetWorldHeight( WorldHeight() );
       
  1263     iPhysicsHandler->SetViewRect( Rect() );
       
  1264 
       
  1265     TRAP_IGNORE( InitPhysicsL() );
       
  1266         
       
  1267     if ( CalculateShownItems( ENoScroll ) != KNoItemSelected )
       
  1268         {
       
  1269         UpdateScrollBar();
       
  1270         DrawNow();
       
  1271         }
       
  1272     }
       
  1273 
       
  1274 // -----------------------------------------------------------------------------
       
  1275 // CAknStylusPopUpMenuContent::Draw
       
  1276 // Draw a control called by window server.
       
  1277 // -----------------------------------------------------------------------------
       
  1278 //    
       
  1279 void CAknStylusPopUpMenuContent::Draw( const TRect& /*aRect*/ ) const
       
  1280     {
       
  1281     if ( AknLayoutUtils::PenEnabled() )
       
  1282         {
       
  1283         CWindowGc& gc = SystemGc();
       
  1284 
       
  1285         for ( TInt i=iFirstItem; i < iItems.Count(); i++ )
       
  1286             {
       
  1287             if ( iItems[i]->iVisibility != KHidden )
       
  1288                 {
       
  1289                 DrawItem( gc, i, ( i == iCurrentItem ) ? EDrawHighlight : 
       
  1290                     ENoHighlight );
       
  1291                 }
       
  1292             }
       
  1293         }
       
  1294     }
       
  1295 
       
  1296 
       
  1297 // -----------------------------------------------------------------------------
       
  1298 // CAknStylusPopUpMenuContent::ListRectFromLayout
       
  1299 // -----------------------------------------------------------------------------
       
  1300 //
       
  1301 TRect CAknStylusPopUpMenuContent::ListRectFromLayout( const TRect& aParent,
       
  1302         const TAknWindowLineLayout& aLineLayout ) const
       
  1303     {
       
  1304     TAknLayoutRect layoutRect;
       
  1305     layoutRect.LayoutRect( aParent, aLineLayout );
       
  1306 
       
  1307     TAknWindowLineLayout listLayout =             
       
  1308         AknLayoutScalable_Avkon::list_touch_menu_pane().LayoutLine();
       
  1309 
       
  1310     TAknLayoutRect listRect; 
       
  1311     listRect.LayoutRect( layoutRect.Rect(), listLayout ); 
       
  1312 
       
  1313     return listRect.Rect();
       
  1314     }
       
  1315 
       
  1316 // -----------------------------------------------------------------------------
       
  1317 // CAknStylusPopUpMenuContent::RectFromLayout
       
  1318 // -----------------------------------------------------------------------------
       
  1319 //
       
  1320 TRect CAknStylusPopUpMenuContent::RectFromLayout( const TRect& aParent,
       
  1321         const TAknWindowLineLayout& aLineLayout ) const
       
  1322     {
       
  1323     TAknLayoutRect layoutRect;
       
  1324     layoutRect.LayoutRect( aParent, aLineLayout );
       
  1325     return layoutRect.Rect();
       
  1326     }
       
  1327 
       
  1328 // -----------------------------------------------------------------------------
       
  1329 // CAknStylusPopUpMenuContent::HandleScrollEventL
       
  1330 // -----------------------------------------------------------------------------
       
  1331 //
       
  1332 void CAknStylusPopUpMenuContent::HandleScrollEventL(
       
  1333         CEikScrollBar* aScrollBar,
       
  1334         TEikScrollEvent /*aEventType*/ )
       
  1335     {
       
  1336     iPhysicsHandler->HandleScrollEvent( aScrollBar->ThumbPosition() );
       
  1337     }
       
  1338     
       
  1339 // -----------------------------------------------------------------------------
       
  1340 // CAknStylusPopUpMenuContent::HandleGainingForeground
       
  1341 // -----------------------------------------------------------------------------
       
  1342 //
       
  1343 void CAknStylusPopUpMenuContent::HandleGainingForeground()
       
  1344     {
       
  1345     
       
  1346     }
       
  1347     
       
  1348 // -----------------------------------------------------------------------------
       
  1349 // CAknStylusPopUpMenuContent::HandleLosingForeground
       
  1350 // -----------------------------------------------------------------------------
       
  1351 //
       
  1352 void CAknStylusPopUpMenuContent::HandleLosingForeground()
       
  1353     {
       
  1354     if ( Observer() )
       
  1355         {
       
  1356         // this will close the stylus popup menu
       
  1357         TRAP_IGNORE( Observer()->HandleControlEventL( this,
       
  1358             MCoeControlObserver::EEventRequestExit ) );
       
  1359         }
       
  1360     }
       
  1361 
       
  1362 
       
  1363 // ---------------------------------------------------------------------------
       
  1364 // CAknStylusPopUpMenuContent::InitPhysicsL
       
  1365 // ---------------------------------------------------------------------------
       
  1366 //   
       
  1367 void CAknStylusPopUpMenuContent::InitPhysicsL()
       
  1368     {
       
  1369     if ( iPhysicsHandler )
       
  1370         {
       
  1371         iPhysicsHandler->InitPhysicsL();
       
  1372         }
       
  1373     }
       
  1374     
       
  1375 // ---------------------------------------------------------------------------
       
  1376 // CAknStylusPopUpMenuContent::Offset
       
  1377 // ---------------------------------------------------------------------------
       
  1378 //     
       
  1379 TInt CAknStylusPopUpMenuContent::Offset() const
       
  1380     {
       
  1381     return iPhysicsHandler->Offset();
       
  1382     }
       
  1383     
       
  1384     
       
  1385 // ---------------------------------------------------------------------------
       
  1386 // CAknStylusPopUpMenuContent::WorldHeight
       
  1387 // ---------------------------------------------------------------------------
       
  1388 //    
       
  1389 TInt CAknStylusPopUpMenuContent::WorldHeight() const
       
  1390     {
       
  1391     TInt visibleItems = 0;
       
  1392     
       
  1393     for ( TInt i = 0; i < iItems.Count(); i++ )
       
  1394         {
       
  1395         if ( iItems[i]->iVisibility == KShown )
       
  1396             {
       
  1397             visibleItems++;
       
  1398             }
       
  1399         }
       
  1400     if ( visibleItems == 0 )
       
  1401         {
       
  1402         return 0;
       
  1403         }
       
  1404             
       
  1405     TRect mainPaneRect;
       
  1406     AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EMainPane,
       
  1407                                        mainPaneRect );
       
  1408     TAknWindowLineLayout listLayout = 
       
  1409        AknLayoutScalable_Avkon::list_single_touch_menu_pane(0).LayoutLine();
       
  1410  
       
  1411     TAknTextLineLayout textLayout = 
       
  1412        AknLayoutScalable_Avkon::list_single_touch_menu_pane_t1().LayoutLine();
       
  1413 
       
  1414     TAknWindowLineLayout unit = 
       
  1415        AknLayoutScalable_Avkon::aid_value_unit2().LayoutLine();
       
  1416     
       
  1417     TInt singleItemHeight = listLayout.iH; 
       
  1418     TInt height = singleItemHeight * visibleItems;
       
  1419     return height;
       
  1420     }
       
  1421     
       
  1422     
       
  1423 // ---------------------------------------------------------------------------
       
  1424 // CAknStylusPopUpMenuContent::UpdateView
       
  1425 // ---------------------------------------------------------------------------
       
  1426 //     
       
  1427 void CAknStylusPopUpMenuContent::UpdateView( TInt aTopItem )
       
  1428     {        
       
  1429     TInt visibleItems = 0;
       
  1430     
       
  1431     for ( TInt i = 0; i < iItems.Count(); i++ )
       
  1432         {
       
  1433         if ( iItems[i]->iVisibility == KShown )
       
  1434             {
       
  1435             if ( visibleItems == aTopItem )
       
  1436                 {
       
  1437                 iFirstItem = i;
       
  1438                 break;
       
  1439                 }
       
  1440             visibleItems ++;
       
  1441             }
       
  1442         }
       
  1443     SizeChanged();    
       
  1444     }
       
  1445     
       
  1446 // ---------------------------------------------------------------------------
       
  1447 // CAknStylusPopUpMenuContent::ContainingItem
       
  1448 // ---------------------------------------------------------------------------
       
  1449 //   
       
  1450 TInt CAknStylusPopUpMenuContent::ContainingItem( const TPoint& aPosition )
       
  1451     { 
       
  1452     for ( TInt i = 0; i < iItems.Count(); i++ )
       
  1453         {
       
  1454         CAknStylusPopUpMenuItem* item = iItems[i];
       
  1455         if ( item->iRect.Contains( aPosition ) && item->iVisibility != KHidden )
       
  1456             {
       
  1457             return i;
       
  1458             }
       
  1459         }
       
  1460     return KNoItemSelected;    
       
  1461     }
       
  1462     
       
  1463 
       
  1464 // ---------------------------------------------------------------------------
       
  1465 // CAknStylusPopUpMenuContent::SetHighlight
       
  1466 // ---------------------------------------------------------------------------
       
  1467 //   
       
  1468 void CAknStylusPopUpMenuContent::SetHighlight( TInt aItem )
       
  1469     {
       
  1470     iCurrentItem = aItem;
       
  1471     DrawDeferred();
       
  1472     }
       
  1473     
       
  1474 // ---------------------------------------------------------------------------
       
  1475 // CAknStylusPopUpMenuContent::CurrentItem
       
  1476 // ---------------------------------------------------------------------------
       
  1477 //   
       
  1478 TInt CAknStylusPopUpMenuContent::CurrentItem() const
       
  1479     {
       
  1480     return iCurrentItem;
       
  1481     }
       
  1482 
       
  1483 // ---------------------------------------------------------------------------
       
  1484 // CAknStylusPopUpMenuContent::SelectItem
       
  1485 // ---------------------------------------------------------------------------
       
  1486 //     
       
  1487 void CAknStylusPopUpMenuContent::SelectItem( TInt aItem )
       
  1488     {
       
  1489     iCurrentItem = aItem;
       
  1490     if ( Observer() )
       
  1491         {
       
  1492         if ( iExtension )
       
  1493             {
       
  1494             iExtension->iInformObserver = EFalse; 
       
  1495             iExtension->iObserverInformed = ETrue; 
       
  1496             }
       
  1497         TRAP_IGNORE(Observer()->HandleControlEventL( this,
       
  1498             MCoeControlObserver::EEventStateChanged ));
       
  1499         }
       
  1500     }
       
  1501