diff -r fcdfafb36fe7 -r aecbbf00d063 uifw/EikStd/coctlsrc/EIKMENUP.CPP --- a/uifw/EikStd/coctlsrc/EIKMENUP.CPP Thu Aug 19 10:11:06 2010 +0300 +++ b/uifw/EikStd/coctlsrc/EIKMENUP.CPP Tue Aug 31 15:28:30 2010 +0300 @@ -1,5 +1,5 @@ /* -* Copyright (c) 2002-2010 Nokia Corporation and/or its subsidiary(-ies). +* Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies). * All rights reserved. * This component and the accompanying materials are made available * under the terms of "Eclipse Public License v1.0" @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -54,6 +55,8 @@ #include #include +#include +#include #include #include #include @@ -61,9 +64,16 @@ #include //For transition effects #include // SetAllParents method #include +#include #include #include +#ifdef RD_UI_TRANSITION_EFFECTS_LIST +#include // LISTBOX EFFECTS IMPLEMENTATION +#include +#include +#endif // RD_UI_TRANSITION_EFFECTS_LIST + #include #include #include @@ -105,15 +115,40 @@ * Extension now contains menu/submenu highlight animation functionality. */ NONSHARABLE_CLASS( CEikMenuPaneExtension ): - public CBase, + public CActive, + public MCoeForegroundObserver, + public MAknsEffectAnimObserver, public MCoeControlObserver, public MAknPhysicsObserver { public: + enum TFlag + { + /** + * If set, animation creation is attempted. If not set, animation will + * never be created. + */ + EFlagUseAnimation = 0 + }; + + enum TScreen + { + EQhdHeight = 360, + EQhdWidth = 640 + }; + CEikMenuPaneExtension(); ~CEikMenuPaneExtension(); void ConstructL( CEikMenuPane* aControl ); + void CreateAnimation(); + void NoAnimIfError( TInt aError ); + void UseNoAnimation(); + void FocusGained(); + void FocusLost(); + + void HandleLayoutSwitch(); + void ChangeHighlightBackground(); void MenuClosed(); void ConstructMenuSctRowL( TDes& aSpecialChars, TInt aResourceId ); @@ -132,7 +167,29 @@ void ChangePosition( TPointerEvent& aPointerEvent ); void CalculateParentEvent( const TPointerEvent& aPointerEvent, TPointerEvent& aParentEvent ); + TRect GetBackgroundRect( const TRect& aWindowRect ) const; + static void AdjustPopupLayoutData( TAknWindowLineLayout& aListScrollPaneLayout ); + + const TAknLayoutText GetMenuItemTextLayout(const TRect& aItemRect, TBool cascade); + +public: // Implementation of MCoeForegroundObserver + void HandleGainingForeground(); + void HandleLosingForeground(); + +public: // Implementation of MAknsEffectAnimObserver + void AnimFrameReady( TInt aError, TInt ); void HandleControlEventL(CCoeControl* aControl,TCoeEvent aEventType); + +protected: // CActive overloads + void DoCancel(); + void RunL(); + +private: // New internal methods + void Play(); + TBool DrawHighlightBackground( CFbsBitGc& aGc ); + void PostDeleteAnimation(); + void CreateAnimationL( const TSize& aHighlightSize ); + void DoResizeL( const TSize& aHighlightSize, TBool aAboutToStart ); public: void ImmediateFeedback( TTouchLogicalFeedback aType, TTouchFeedbackType aFbType ); @@ -140,10 +197,14 @@ public: void StartCascadeMenuAppearTransition(); +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + void CalcItemSize( MAknListBoxTfxInternal* transApi ) const; +#endif + /** * Prepares cascade menu for item specific commands. */ - void PrepareCascadeForItemCommandsL(); + void PrepareCascadeForItemCommands(); /** * Returns ETrue if this menu pane belongs to a CS menu. @@ -175,7 +236,7 @@ * * @return ETrue if highlight is enabled */ - TBool HighlightEnabled(); + TBool HighlightEnabled(); /** * Sets the default highlight to options menu @@ -184,6 +245,8 @@ void SetDefaultHighlight(); public: // Data + TBool iHasIcon; + TBool iIsPenEnable; CFbsBitmap* iCascadeBitmap; CFbsBitmap* iCascadeBitmapMask; CAknsFrameBackgroundControlContext* iBgContext; @@ -194,7 +257,14 @@ CFbsBitmap* iRadioButtonBitmapMask; // mask for the above bitmap TBool iHasRadioGroup; // is ETrue if submenu contains radio button group. TInt iSelectedRadioButtonItem; // index of the radio button item which is currently selected (one must be selected) + CCoeControl* iGrabbingCBAComponent; // component control of CBA which is currently grabbing the pointer CEikMenuPane* iControl; + CAknsEffectAnim* iAnimation; + /** + * Stored flags are explained in enumeration TFlags. + */ + TBitFlags32 iAnimFlags; + CAknCharMap* iSct; // Menu SCT row, created only when needed. TBool iSctHighlighted; // No "normal" menu item can be highlighted if ETrue @@ -207,17 +277,26 @@ // needs to be mutable since we need to get information from Draw methods // (that are declared const) mutable TRect iCascadeDRect; + TBool iTransitionsOn; // Transitions FtMgr flag on TBool iShowCascadeTransition; // For later deletion of cascade menu, this allows the transition system // to correctly handle the aborted transitions CEikMenuPane* iCascadeMenuObject; TBool iDraggedOutside; TPointerEvent iLastPointerEvent; + +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + CWindowGc* iGc; +#endif TInt iItemsThatFitInView; TRect iScrollBarRect; TRect iSctRect; + TInt iTotalNumberOfItemsInView; // this value includes partial items + + CIdle* iTaskSwapIdle; CRedirectionListener* iRedirectionListener; + TRect iSBRect; RWindow* iMenuPaneWindow; // Not own, used by SCT TBool iLaunchCascadeMenu; TBool isUpdateScrollDirectly; @@ -236,39 +315,13 @@ ESingleClickEnabled, EHideItemSpecificCommands, EContextSensitive, - ESkipScrollbarUpdate, - EHighlightEnabled, - EHideViewSpecificCommands, - EHideMarkAndUnmark, - EHideItemActionCommands + EHighlightEnabled }; /** * Menu pane extension flags. */ TBitFlags iFlags; - - /** - * Cached rectangle occupied by menu items (excluding scrollbar's area). - */ - TRect iItemAreaRect; - - /** - * Cached rectangle occupied by menu items and scrollbar. - */ - TRect iMenuAreaRect; - - /** - * Index of the item were highlight was previously drawn to. - * Can be KErrNotFound. - */ - TInt iHighlightedItem; - - /** - * Scrollbar's desired visibility. This is calculated in conjunction with - * menu pane's size and used later on when calculating scrollbar's layout. - */ - CEikScrollBarFrame::TScrollBarVisibility iScrollbarVisibility; private: // Data CPeriodic* iTimer; // timer to launch submenu, own @@ -400,6 +453,12 @@ inline void CEikMenuPane::CMenuScroller::SetTopItemIndex(TInt aIndex) { iTopItemIndex=aIndex; +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + if ( iMenuPane.iExtension ) + { + iTopItemIndex = aIndex; + } +#endif } inline CIdle* CEikMenuPane::CMenuScroller::Idle() const @@ -415,8 +474,16 @@ iLastFeedbackTopItemIndex = 0; iPressedDown = EFalse; iFlickActive = EFalse; - - TRect rect( iMenuPaneRect ); + + TRect rect; + if ( !iControl->iOwner ) + { + rect = iMenuPaneRect; + } + else + { + rect = iControl->Rect(); + } TInt itemHeight = iControl->iItemHeight; TInt itemsInRect = rect.Height() / itemHeight; @@ -470,18 +537,19 @@ void CEikMenuPaneExtension::ViewPositionChanged( const TPoint& aNewPosition, TBool aDrawNow, TUint /*aFlags*/ ) - { + { _AKNTRACE_FUNC_ENTER; - TInt delta = iViewPosition.iY - aNewPosition.iY; - - if ( !iControl->iItemArray || delta == 0 ) + if ( !iControl->iItemArray ) { return; } - + iListTopIndex = aNewPosition.iY - iViewHeight / 2; + iListBottomIndex = aNewPosition.iY + iViewHeight - iViewHeight / 2; + TInt delta = iViewPosition.iY - aNewPosition.iY; + DoOffset( delta ); iViewPosition = aNewPosition; @@ -490,29 +558,18 @@ _AKNTRACE( "delta = %d", delta ); _AKNTRACE( "iViewPosition(%d,%d)", iViewPosition.iX, iViewPosition.iY ); - //here checking the delta whether it is changed. - //if it is changed,the view must be drawn using the below code. - if ( delta != 0 ) - { - aDrawNow = ETrue; - } if ( aDrawNow ) { - if ( iFlags.IsClear( ESkipScrollbarUpdate ) ) - { - TRAP_IGNORE( iControl->DoUpdateScrollBarL() ); - } - - // Redraw only item area if scrollbar is invisible, otherwise include - // also scrollbar's area in order to avoid drawdeferred. - TRect drawRect( iItemAreaRect ); - - if ( iScrollbarVisibility == CEikScrollBarFrame::EOn ) - { - drawRect = iMenuAreaRect; - } - - iControl->DrawNow( drawRect ); + TRAP_IGNORE( iControl->DoUpdateScrollBarL() ); + + if ( iControl->iOwner ) // Submenu + { + iControl->DrawNow(); + } + else + { + iControl->DrawNow( TRect( iMenuPaneRect.Size() ) ); + } } _AKNTRACE_FUNC_EXIT; } @@ -573,18 +630,24 @@ if ( iFlickActive || iPanningActive ) { if ( ( aOffset>0 && iListTopIndex <= listBottomLimit && iListTopIndex >= -iViewHeight ) || - ( aOffset<0 && iListBottomIndex >= 0 && iListBottomIndex <= listBottomLimit+iViewHeight ) ) - { - if ( iPhysics ) + ( aOffset<0 && iListBottomIndex >= 0 && iListBottomIndex <= listBottomLimit+iViewHeight ) ) + { + if ( iPhysics ) { - switch(iPhysics->OngoingPhysicsAction()) + TTouchFeedbackType feedbackType = ETouchFeedbackVibra; + switch( iPhysics->OngoingPhysicsAction() ) { - case CAknPhysics::EAknPhysicsActionBouncing: case CAknPhysics::EAknPhysicsActionDragging: + { + feedbackType = static_cast ( ETouchFeedbackVibra | ETouchFeedbackAudio ); + } case CAknPhysics::EAknPhysicsActionFlicking: - ImmediateFeedback( ETouchFeedbackSensitiveList, - ETouchFeedbackVibra ); + case CAknPhysics::EAknPhysicsActionBouncing: + { + ImmediateFeedback( ETouchFeedbackSensitiveItem, + feedbackType ); break; + } default: break; } @@ -673,6 +736,14 @@ { _AKNTRACE_FUNC_ENTER; iFlickActive = EFalse; +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + MAknListBoxTfx* tfxApi = CAknListLoader::TfxApi( iGc ); + + if ( tfxApi ) + { + tfxApi->EnableEffects( ETrue ); + } +#endif // RD_UI_TRANSITION_EFFECTS_LIST _AKNTRACE_FUNC_EXIT; } @@ -865,6 +936,7 @@ // ----------------------------------------------------------------------------- // CEikMenuPaneExtension::CEikMenuPaneExtension() : + CActive( EPriorityHigh ), // Initialise data members to zero iCascadeBitmap( NULL ), iCascadeBitmapMask( NULL ), @@ -876,10 +948,16 @@ iRadioButtonBitmapMask( NULL ), iHasRadioGroup( EFalse ), iSelectedRadioButtonItem( KNoSelectedRadioButtonItem ), + iGrabbingCBAComponent( NULL ), iControl( NULL ), + iAnimation( NULL ), + iAnimFlags ( 0 ), iSct( NULL ), iSctHighlighted( EFalse ), iSpecialCharPointed( EFalse ) +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + ,iGc ( NULL ) +#endif // RD_UI_TRANSITION_EFFECTS_LIST ,iVerticalOffset( 0 ) ,iPhysics( NULL ) ,iListTopIndex( 0 ) @@ -889,9 +967,9 @@ ,iFeedback( MTouchFeedback::Instance() ) ,iLastFeedbackTopItemIndex( 0 ) { - iItemsReadyForPenSelection = !AknLayoutUtils::PenEnabled(); + iIsPenEnable = AknLayoutUtils::PenEnabled(); + iItemsReadyForPenSelection = !iIsPenEnable; iNextHighlightItem = KErrNotFound; - iHighlightedItem = KErrNotFound; } // ----------------------------------------------------------------------------- @@ -902,6 +980,17 @@ CEikMenuPaneExtension::~CEikMenuPaneExtension() { _AKNTRACE_FUNC_ENTER; +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + if ( CAknListLoader::TfxApiInternal( iGc ) ) + { + delete iGc; + } +#endif + Cancel(); // Cancel possibly pending request + + // Stop receiving foreground events + CCoeEnv* env = CCoeEnv::Static(); + env->RemoveForegroundObserver( *this ); delete iCascadeBitmap; iCascadeBitmap = NULL; @@ -926,6 +1015,9 @@ iControl = NULL; + delete iAnimation; + iAnimation = NULL; + delete iSct; iSct = NULL; @@ -961,6 +1053,8 @@ { ASSERT( aControl ); iControl = aControl; + iAnimFlags.Set( EFlagUseAnimation ); // Animations are created by default + CActiveScheduler::Add( this ); iDraggedOutside = EFalse; iLaunchCascadeMenu = EFalse; iButtonDownItem = KErrNotFound; @@ -970,6 +1064,11 @@ // Delays submenu opening during appear transitions iRedirectionListener = new ( ELeave ) CRedirectionListener( *this ); } +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + iGc = CAknListLoader::CreateTfxGc( *aControl, + iControl->iScroller->iTopItemIndex, + iTotalNumberOfItemsInView ); +#endif // RD_UI_TRANSITION_EFFECTS_LIST if ( static_cast( iControl->ControlEnv()->AppUi() )->IsSingleClickCompatible() ) { @@ -985,6 +1084,55 @@ KAknsIIDQsnFrPopup, TRect( 0, 0, 1, 1 ), TRect( 0, 0, 1, 1 ), EFalse ); } +// ----------------------------------------------------------------------------- +// CEikMenuPaneExtension::CreateAnimation +// ----------------------------------------------------------------------------- +// +void CEikMenuPaneExtension::CreateAnimation() + { +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + return; +#else + if( !iAnimation && iAnimFlags.IsSet( EFlagUseAnimation ) ) + { + TRect rect = iControl->HighlightRect(); + TRAPD( err, CreateAnimationL( rect.Size() ) ); + if( KErrNone != err ) + { + // Animation has not been drawn -> no need for repaint + UseNoAnimation(); + } + } +#endif //RD_UI_TRANSITION_EFFECTS_LIST + } + +// ----------------------------------------------------------------------------- +// CEikMenuPaneExtension::NoAnimIfError +// ----------------------------------------------------------------------------- +// +void CEikMenuPaneExtension::NoAnimIfError( TInt aError ) + { + if( KErrNone != aError ) + UseNoAnimation(); + } + +// ----------------------------------------------------------------------------- +// CEikMenuPaneExtension::UseNoAnimation +// Falls back to normal highlight rendering. +// ----------------------------------------------------------------------------- +// +void CEikMenuPaneExtension::UseNoAnimation() + { + delete iAnimation; + iAnimation = NULL; + + // Do not attempt to create animations in the future + iAnimFlags.Clear( EFlagUseAnimation ); + + // Stop receiving foreground events + CCoeEnv* env = CCoeEnv::Static(); + env->RemoveForegroundObserver( *this ); + } // ----------------------------------------------------------------------------- // CEikMenuPaneExtension::StartCascadeMenuTimerL @@ -1009,7 +1157,6 @@ _AKNTRACE_FUNC_EXIT; } - // ----------------------------------------------------------------------------- // CEikMenuPaneExtension::StopCascadeMenuTimer // Stops the timer for the sub menu launch @@ -1113,7 +1260,6 @@ _AKNTRACE_FUNC_EXIT; } - // ----------------------------------------------------------------------------- // CEikMenuPaneExtension::HighlightTimerCallBack // Callback function of the timer for pressed down highlight @@ -1165,12 +1311,11 @@ { if ( !iControl->iSBFrame ) { - return; - } - - TRect scrollBarRect( iControl->iSBFrame->VerticalScrollBar()->Rect() ); - TPoint scrollerTl( scrollBarRect.iTl ); - TPoint scrollerBr( scrollBarRect.iBr ); + iControl->CreateScrollBarFrame(); + } + TRect scrollBarRect = iControl->iSBFrame->VerticalScrollBar()->Rect(); + TPoint scrollerTl = scrollBarRect.iTl; + TPoint scrollerBr = scrollBarRect.iBr; TRect gapRect; // For layout that left to right if ( !AknLayoutUtils::LayoutMirrored() ) @@ -1218,14 +1363,158 @@ TPointerEvent& aParentEvent ) { aParentEvent.iModifiers = aPointerEvent.iModifiers; - TPoint subPos = iControl->Position(); - TPoint ownerPos = iControl->iOwner->Position(); + TPoint subPos = iControl->PositionRelativeToScreen(); + TPoint ownerPos = iControl->iOwner->PositionRelativeToScreen(); aParentEvent.iPosition.SetXY ( aPointerEvent.iPosition.iX + subPos.iX - ownerPos.iX, aPointerEvent.iPosition.iY + subPos.iY - ownerPos.iY); aParentEvent.iType = aPointerEvent.iType; } +// ----------------------------------------------------------------------------- +// CEikMenuPaneExtension::GetBackgroundRect +// Get background rect for landscape mode of menu pane. +// ----------------------------------------------------------------------------- +// +TRect CEikMenuPaneExtension::GetBackgroundRect( const TRect& aWindowRect ) const + { + return aWindowRect; + } + +// ----------------------------------------------------------------------------- +// CEikMenuPaneExtension::AdjustPopupLayoutData +// Adjust popup layout data for main menu pane in landscape mode +// ----------------------------------------------------------------------------- +// +void CEikMenuPaneExtension::AdjustPopupLayoutData( TAknWindowLineLayout& aListScrollPaneLayout ) + { + TRect screenRect; + AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EScreen, screenRect ); + AknLayoutUtils::TAknCbaLocation cbaPosition = AknLayoutUtils::CbaLocation(); + + if ( screenRect.Width() == EQhdWidth && screenRect.Height() == EQhdHeight + && cbaPosition == AknLayoutUtils::EAknCbaLocationBottom ) + { + if ( !AknLayoutUtils::LayoutMirrored() ) + { + aListScrollPaneLayout.ir -= 32; + } + else + { + aListScrollPaneLayout.il -= 32; + } + } + } + + +// ----------------------------------------------------------------------------- +// CEikMenuPaneExtension::GetMenuItemTextLayout +// Get Layout of menu item text. +// ----------------------------------------------------------------------------- +// +const TAknLayoutText CEikMenuPaneExtension::GetMenuItemTextLayout(const TRect& aItemRect, TBool cascade) + { + TAknTextLineLayout menuTextLayout; + + if ( !iControl->iOwner ) + { + menuTextLayout = AknLayoutScalable_Avkon::list_single_pane_t1_cp2( cascade ? 3 : 0 ).LayoutLine(); + } + else + { + if ( iHasIcon ) + { + menuTextLayout = TAknTextLineLayout( AknLayoutScalable_Avkon::list_single_popup_submenu_pane_t1( 1 ).LayoutLine() ); + } + else + { + menuTextLayout = TAknTextLineLayout( AknLayoutScalable_Avkon::list_single_popup_submenu_pane_t1( 0 ).LayoutLine() ); + } + } + + TAknLayoutText textRect; + textRect.LayoutText( aItemRect, menuTextLayout ); + return textRect; + } + + +// ----------------------------------------------------------------------------- +// CEikMenuPaneExtension::FocusGained +// The owning control has gained focus -> animation should be continued. +// ----------------------------------------------------------------------------- +// +void CEikMenuPaneExtension::FocusGained() + { + Play(); + } + +// ----------------------------------------------------------------------------- +// CEikMenuPaneExtension::FocusLost +// The owning control has lost focus -> no running animation (even if the +// control is partially visible). +// ----------------------------------------------------------------------------- +// +void CEikMenuPaneExtension::FocusLost() + { + if( iAnimation ) + { + NoAnimIfError( iAnimation->Pause() ); + } + } + +// ----------------------------------------------------------------------------- +// CEikMenuPaneExtension::HandleLayoutSwitch +// ----------------------------------------------------------------------------- +// +void CEikMenuPaneExtension::HandleLayoutSwitch() + { + if( iAnimation ) // Animation exists -> try to resize + { + TRect rect( iControl->HighlightRect() ); + + // Resize animation + TBool aboutToStart = ETrue; + if( iAnimation->State() == EAknsAnimStateStopped ) + aboutToStart = EFalse; + + TRAPD( err, DoResizeL( rect.Size(), aboutToStart ) ); + NoAnimIfError( err ); + } + } + +// ----------------------------------------------------------------------------- +// CEikMenuPaneExtension::ChangeHighlightBackground +// ----------------------------------------------------------------------------- +// +void CEikMenuPaneExtension::ChangeHighlightBackground() + { + // Every time the current list item is changed we need to change the + // animation input layer (animated element is the highlight bacground that + // can differ between highlight positions). + if( iAnimation ) + { + if( iAnimation->State() == EAknsAnimStateStopped ) + { + // Input layers don't exist when stopped or finished. We need to + // resize to create the input layers and to update the output + // layer. + + TRAPD( err, DoResizeL( iAnimation->Size(), EFalse ) ); + NoAnimIfError( err ); + } + else // Either paused, running or finished + { + // Update the highlight background + if( iAnimation->InputRgbGc() ) + DrawHighlightBackground( *iAnimation->InputRgbGc() ); + + // We need to update the output frame (otherwise the highlight + // would drawn with the old output before the next new animation + // frame). + NoAnimIfError( iAnimation->UpdateOutput() ); + } + } + } // ----------------------------------------------------------------------------- // CEikMenuPaneExtension::MenuClosed @@ -1234,9 +1523,20 @@ void CEikMenuPaneExtension::MenuClosed() { _AKNTRACE_FUNC_ENTER; + delete iAnimation; + iAnimation = NULL; + + CCoeEnv* env = CCoeEnv::Static(); + env->RemoveForegroundObserver( *this ); + + iAnimFlags.Set( EFlagUseAnimation ); + delete iSct; iSct = NULL; iSctHighlighted = EFalse; +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + iSctRect = TRect::EUninitialized; +#endif if ( iCba ) { @@ -1249,14 +1549,197 @@ } iFlags.Clear( EHideItemSpecificCommands ); - iFlags.Clear( EHideItemActionCommands ); iFlags.Clear( EContextSensitive ); iFlags.Clear( EHighlightEnabled ); - iFlags.Clear( EHideViewSpecificCommands ); - iFlags.Clear( EHideMarkAndUnmark ); _AKNTRACE_FUNC_EXIT; } +// ----------------------------------------------------------------------------- +// CEikMenuPaneExtension::HandleGainingForeground +// The application has gained foreground -> animation should be continued. +// ----------------------------------------------------------------------------- +// +void CEikMenuPaneExtension::HandleGainingForeground() + { + // It is safe to start animation in this method because animation is + // deleted when the menu is closed -> it is not possible that menu receives + // foreground event while it is not visible and the animation exists. + + // We need to check if the menu has focus (to prevent running nonfocused + // animation because also the nonfocused menu (menu/submenu) receives + // foreground events) + Play(); + } + +// ----------------------------------------------------------------------------- +// CEikMenuPaneExtension::HandleLosingForeground +// The application lost foreground -> no running animation (even if the +// application is partially visible). +// ----------------------------------------------------------------------------- +// +void CEikMenuPaneExtension::HandleLosingForeground() + { + if( iAnimation ) + { + NoAnimIfError( iAnimation->Stop() ); + } + } + +// ----------------------------------------------------------------------------- +// CEikMenuPaneExtension::AnimFrameReady +// ----------------------------------------------------------------------------- +// +void CEikMenuPaneExtension::AnimFrameReady( TInt aError, TInt ) + { + if( KErrNone != aError ) + { + // Animation has failed to run -> schedule the animation for + // deletion to fall back to normal rendering. + PostDeleteAnimation(); + } + else if( iControl ) // Frame ok + { + if ( iControl->IsVisible() ) + { + iControl->RepaintHighlight(); + } + } + } + +// ----------------------------------------------------------------------------- +// CEikMenuPaneExtension::DoCancel +// ----------------------------------------------------------------------------- +// +void CEikMenuPaneExtension::DoCancel() + { + // Required method, but not needed + } + + +// ----------------------------------------------------------------------------- +// CEikMenuPaneExtension::RunL +// Postponed animation deletion is done here +// ----------------------------------------------------------------------------- +// +void CEikMenuPaneExtension::RunL() + { + UseNoAnimation(); + } + +// ----------------------------------------------------------------------------- +// CEikMenuPaneExtension::Play +// ----------------------------------------------------------------------------- +// +void CEikMenuPaneExtension::Play() + { + if( !iAnimation || !iControl->IsFocused() ) + { + return; + } + + // No need to start running/finished animation + if( EAknsAnimStateRunning == iAnimation->State() || + EAknsAnimStateFinished == iAnimation->State() ) + { + return; + } + + CAknAppUi* aui = static_cast(CEikonEnv::Static()->AppUi()); + if( !aui->IsForeground() ) + { + return; + } + + if( EAknsAnimStatePaused == iAnimation->State() ) + { + NoAnimIfError( iAnimation->Continue() ); + } + else if( EAknsAnimStateStopped == iAnimation->State() ) + { + if( iAnimation->NeedsInputLayer() ) + { + TRAPD( err, DoResizeL( iAnimation->Size(), ETrue ) ); + NoAnimIfError( err ); + + if( KErrNone != err ) + return; + } + + NoAnimIfError( iAnimation->Start() ); + } + } + +// ----------------------------------------------------------------------------- +// CEikMenuPaneExtension::DrawHighlightBackground +// Draws skinned highlight background to the provided graphics context. +// ----------------------------------------------------------------------------- +// +TBool CEikMenuPaneExtension::DrawHighlightBackground( CFbsBitGc& aGc ) + { + // Draw the background under the current highlight. This simplified + // drawing, we only grab a piece from the list background bitmap. + MAknsSkinInstance* skin = AknsUtils::SkinInstance(); + + return AknsDrawUtils::DrawBackground( skin, iBgContext, iControl, aGc, TPoint(0,0), + iControl->HighlightRect(), + KAknsDrawParamRGBOnly ); + } + +// ----------------------------------------------------------------------------- +// CEikMenuPaneExtension::PostDeleteAnimation +// Schedules the animation for deletion by activating the extension itself. +// Deletion is postponed because in many error/failure occasions the caller has +// been animation and direct deletion is possibly not safe (because function +// stack would return through the deleted object). +// ----------------------------------------------------------------------------- +// +void CEikMenuPaneExtension::PostDeleteAnimation() + { + TRequestStatus* status = &iStatus; + User::RequestComplete( status, KErrNone ); + SetActive(); + } + +// ----------------------------------------------------------------------------- +// CEikMenuPaneExtension::CreateAnimationL +// ----------------------------------------------------------------------------- +// +void CEikMenuPaneExtension::CreateAnimationL( const TSize& aHighlightSize ) + { + // Create animation + CCoeEnv* env = CCoeEnv::Static(); + env->AddForegroundObserverL( *this ); + + delete iAnimation; + iAnimation = NULL; + + iAnimation = CAknsEffectAnim::NewL( this ); + TBool ok = iAnimation->ConstructFromSkinL( KAknsIIDQsnAnimList ); + + if( !ok ) // Animation for the ID was not found from the skin + { + User::Leave( KErrNotFound ); + } + + DoResizeL( aHighlightSize, ETrue ); + + Play(); + } + +// ----------------------------------------------------------------------------- +// CEikMenuPaneExtension::DoResizeL +// ----------------------------------------------------------------------------- +// +void CEikMenuPaneExtension::DoResizeL( + const TSize& aHighlightSize, TBool aAboutToStart ) + { + iAnimation->BeginConfigInputLayersL( aHighlightSize, aAboutToStart ); + + if( iAnimation->InputRgbGc() ) + DrawHighlightBackground( *iAnimation->InputRgbGc() ); + + iAnimation->EndConfigInputLayersL(); + } // ----------------------------------------------------------------------------- // CEikMenuPaneExtension::ConstructMenuSctRowL @@ -1279,8 +1762,11 @@ if ( renew && iMenuPaneWindow && iControl ) { iSct->SetContainerWindowL( *iControl ); - iSct->SetGloballyCapturing( ETrue ); - iSct->SetPointerCapture( ETrue ); + if ( AknLayoutUtils::PenEnabled() ) + { + iSct->SetGloballyCapturing( ETrue ); + iSct->SetPointerCapture( ETrue ); + } } _AKNTRACE_FUNC_EXIT; } @@ -1305,8 +1791,11 @@ if ( renew && iMenuPaneWindow && iControl) { iSct->SetContainerWindowL( *iControl ); - iSct->SetGloballyCapturing( ETrue ); - iSct->SetPointerCapture( ETrue ); + if ( AknLayoutUtils::PenEnabled() ) + { + iSct->SetGloballyCapturing( ETrue ); + iSct->SetPointerCapture( ETrue ); + } } } @@ -1317,10 +1806,13 @@ void CEikMenuPaneExtension::HandleControlEventL(CCoeControl* /*aControl*/,TCoeEvent aEventType) { _AKNTRACE_FUNC_ENTER; - if ( aEventType == EEventStateChanged ) - { - // Something has been selected from CharMap - iSpecialCharPointed = ETrue; + if ( AknLayoutUtils::PenEnabled() ) + { + if(aEventType == EEventStateChanged) + { + // Something has been selected from CharMap + iSpecialCharPointed = ETrue; + } } _AKNTRACE( "aEventType = %d", aEventType ); _AKNTRACE_FUNC_EXIT; @@ -1335,8 +1827,8 @@ TTouchLogicalFeedback aType, TTouchFeedbackType aFbType = TTouchFeedbackType( ETouchFeedbackAudio | ETouchFeedbackVibra )) - { - if( iFeedback && AknLayoutUtils::PenEnabled() ) + { + if ( iFeedback ) { iFeedback->InstantFeedback( iControl, aType, aFbType, TPointerEvent() ); } @@ -1344,10 +1836,10 @@ // ----------------------------------------------------------------------------- -// CEikMenuPaneExtension::PrepareCascadeForItemCommandsL -// ----------------------------------------------------------------------------- -// -void CEikMenuPaneExtension::PrepareCascadeForItemCommandsL() +// CEikMenuPaneExtension::PrepareCascadeForItemCommands +// ----------------------------------------------------------------------------- +// +void CEikMenuPaneExtension::PrepareCascadeForItemCommands() { if ( iFlags.IsSet( ESingleClickEnabled ) && iControl->iOwner @@ -1358,16 +1850,9 @@ { iFlags.Set( EContextSensitive ); } - else - { - if ( ownerFlags.IsSet( EHideItemSpecificCommands ) ) - { - iControl->SetItemCommandsStateL( ETrue ); - } - if ( ownerFlags.IsSet( EHideItemActionCommands ) ) - { - iControl->SetItemActionsStateL( ETrue ); - } + else if ( ownerFlags.IsSet( EHideItemSpecificCommands ) ) + { + iControl->SetItemCommandsDimmed(); } } } @@ -1808,13 +2293,6 @@ { _AKNTRACE_FUNC_ENTER; AKNTASHOOK_REMOVE(); - - if ( iIsDeleted ) - { - *iIsDeleted = ETrue; - iIsDeleted = NULL; - } - CloseCascadeMenu(); if ( !ItemArrayOwnedExternally() ) { @@ -1884,12 +2362,27 @@ CheckCreateScrollerL(); CheckCreateExtensionL(); + iExtension->iTransitionsOn = FeatureManager::FeatureSupported( KFeatureIdUiTransitionEffects ); + CreateWindowL( iCoeEnv->RootWin() ); EnableWindowTransparency(); SetAllowStrayPointers(); EnableDragEvents(); - iItemHeight = CalculateItemHeight(); + TAknWindowLineLayout menuLineLayout; + if ( iOwner ) // submenu + { + menuLineLayout = AknLayoutScalable_Avkon::list_single_popup_submenu_pane( 0 ).LayoutLine(); + } + else + { + menuLineLayout = AknLayoutScalable_Avkon::list_single_pane_cp2( 0 ).LayoutLine(); + } + + TRect windowRect = Rect(); + TAknLayoutRect menuLayoutRect; + menuLayoutRect.LayoutRect( windowRect, menuLineLayout ); + iItemHeight = menuLayoutRect.Rect().Height(); if ( iExtension->iSct ) { @@ -1897,12 +2390,15 @@ iExtension->iMenuPaneWindow = window; iExtension->iSct->SetContainerWindowL( *this ); - // This is effectively the same as CCoeControl::EnableDragEvents() - // which is protected. - window->PointerFilter( EPointerFilterDrag, 0 ); - iExtension->iSct->SetGloballyCapturing( ETrue ); - iExtension->iSct->SetPointerCapture( ETrue ); - iExtension->iSct->SetObserver(iExtension); + if ( AknLayoutUtils::PenEnabled() ) + { + // This is effectively the same as CCoeControl::EnableDragEvents() + // which is protected. + window->PointerFilter( EPointerFilterDrag, 0 ); + iExtension->iSct->SetGloballyCapturing( ETrue ); + iExtension->iSct->SetPointerCapture( ETrue ); + iExtension->iSct->SetObserver(iExtension); + } } if ( iOwner ) // submenu @@ -1920,6 +2416,7 @@ User::Leave( KErrNoMemory ); Window().SetOrdinalPosition( 0 ); + Window().SetPointerGrab( ETrue ); SetGloballyCapturing( ETrue ); @@ -1943,7 +2440,19 @@ } CreateItemArrayL(); - iItemHeight = CalculateItemHeight(); + TAknWindowLineLayout menuLineLayout; + if ( iOwner ) // submenu + { + menuLineLayout = AKN_LAYOUT_WINDOW_list_single_popup_submenu_pane( 0, 0 ); + } + else + { + menuLineLayout = AKN_LAYOUT_WINDOW_list_single_popup_menu_pane( 0 ); + } + TRect windowRect = Rect(); + TAknLayoutRect menuLayoutRect; + menuLayoutRect.LayoutRect( windowRect, menuLineLayout ); + iItemHeight = menuLayoutRect.Rect().Height(); CheckCreateScrollerL(); CheckCreateExtensionL(); @@ -2266,20 +2775,7 @@ iEditMenuObserver->DynInitMenuPaneL( aCascadeMenuId, iCascadeMenuPane ); } - if ( iExtension->iFlags.IsSet( CEikMenuPaneExtension::EHideMarkAndUnmark ) ) - { - TInt pos; - if ( iCascadeMenuPane->MenuItemExists( EAknCmdMark, pos ) ) - { - iCascadeMenuPane->SetItemDimmed( EAknCmdMark, ETrue ); - } - if ( iCascadeMenuPane->MenuItemExists( EAknCmdUnmark, pos ) ) - { - iCascadeMenuPane->SetItemDimmed( EAknCmdUnmark, ETrue ); - } - } - - iCascadeMenuPane->iExtension->PrepareCascadeForItemCommandsL(); + iCascadeMenuPane->iExtension->PrepareCascadeForItemCommands(); iCascadeMenuPane->iExtension->EnableHighlight( EFalse ); iCascadeMenuPane->FilterDimmedItems(); @@ -2293,13 +2789,16 @@ iExtension->StartCascadeMenuAppearTransition(); } - TTouchLogicalFeedback fbLogicalType = ETouchFeedbackPopUp; - if ( CAknTransitionUtils::TransitionsEnabled( AknTransEffect::EComponentTransitionsOff ) ) - { - fbLogicalType = ETouchFeedbackSubMenuOpened; - } - iExtension->ImmediateFeedback( fbLogicalType, + if( AknLayoutUtils::PenEnabled() ) + { + TTouchLogicalFeedback fbLogicalType = ETouchFeedbackPopUp; + if ( CAknTransitionUtils::TransitionsEnabled( AknTransEffect::EComponentTransitionsOff ) ) + { + fbLogicalType = ETouchFeedbackPopupOpen; + } + iExtension->ImmediateFeedback( fbLogicalType, ETouchFeedbackVibra ); + } _AKNTRACE_FUNC_EXIT; } @@ -2320,11 +2819,16 @@ numItemsInPane = iItemArray->Count(); } - if ( iExtension && iExtension->iSct ) + if ( iExtension->iSct ) { numItemsInPane++; } + TInt maxNumItemsInMenu = AknLayoutScalable_Avkon:: + list_single_pane_cp2_ParamLimits().LastRow() + 1; + TInt maxNumItemsInSubMenu = AknLayoutScalable_Avkon:: + list_single_popup_submenu_pane_ParamLimits().LastRow() + 1; + TInt maxItemsInView = NumberOfItemsThatFitInView(); if (iExtension && iExtension->iSct) @@ -2362,6 +2866,12 @@ iExtension->iPressedDown = EFalse; iExtension->SetOffset( 0 ); + iExtension->iHasIcon = MenuHasIcon(); + + if ( iExtension->iTransitionsOn ) + { + CAknTransitionUtils::SetAllParents( this ); + } const TSize screenSize( iEikonEnv->EikAppUi()->ApplicationRect().Size() ); @@ -2382,7 +2892,11 @@ SetDefaultHighlight(); } - SetRect( CalculateSizeAndPosition() ); + TRect rect( CalculateSizeAndPosition() ); + TPoint newPos( rect.iTl ); + TSize menuSize( rect.Size() ); + + SetExtent( newPos, menuSize ); // We need to set the background context when calling create for the // first time. Otherwise iExtension->iBgContext would have tiny @@ -2390,6 +2904,15 @@ // white. UpdateBackgroundContext( Rect() ); + // The extent has been set. This is the first safe point in code to + // construct animations (because before this highlight related layout code + // will produce invalid results + if( iExtension ) + { + // Creates animation only if it does not exist + iExtension->CreateAnimation(); + } + // Initialize physics engine TRAP_IGNORE ( iExtension->InitPhysicsL() ); @@ -2444,6 +2967,8 @@ TAknsItemID frameIID; TAknsItemID frameCenterIID; + TRect backgroundRect( iExtension->GetBackgroundRect( aWindowRect ) ); + if( iOwner ) //for sub menu { topLeft.LayoutRect( aWindowRect, SkinLayout::Submenu_skin_placing_Line_2() ); @@ -2453,8 +2978,8 @@ } else { - topLeft.LayoutRect( aWindowRect, SkinLayout::Popup_windows_skin_placing__frame_general__Line_2() ); - bottomRight.LayoutRect( aWindowRect, SkinLayout::Popup_windows_skin_placing__frame_general__Line_5() ); + topLeft.LayoutRect( backgroundRect, SkinLayout::Popup_windows_skin_placing__frame_general__Line_2() ); + bottomRight.LayoutRect( backgroundRect, SkinLayout::Popup_windows_skin_placing__frame_general__Line_5() ); frameIID = KAknsIIDQsnFrPopup; frameCenterIID = KAknsIIDQsnFrPopupCenterMenu; } @@ -2514,8 +3039,22 @@ _AKNTRACE( "previousTopItem = %d", previousTopItem ); _AKNTRACE( "previousSelectedItem = %d", previousSelectedItem ); - SetSelectedItem( aNewSelectedItem ); - + ActivateGc(); +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + MAknListBoxTfxInternal *transApi = CAknListLoader::TfxApiInternal( iExtension->iGc ); + if ( transApi ) + { + iExtension->iGc->Activate( *DrawableWindow() ); + } + CWindowGc& gc = transApi ? *iExtension->iGc : SystemGc(); +#else + CWindowGc& gc = SystemGc(); +#endif // RD_UI_TRANSITION_EFFECTS_LIST + PrepareGcForDrawingItems( gc ); + + // Scrollers top item index must be updated first because setting selected + // item results in animation redraw (which requires knowledge about the + // current top item). if ( aNewSelectedItem >= 0 ) { ScrollToMakeItemVisible( aNewSelectedItem ); @@ -2525,10 +3064,6 @@ ScrollToMakeItemVisible( 0 ); } - ActivateGc(); - CWindowGc& gc = SystemGc(); - PrepareGcForDrawingItems( gc ); - TInt topItem = iScroller->TopItemIndex(); TInt bottomItem = topItem + NumberOfItemsThatFitInView(); if( bottomItem > NumberOfItemsInPane() ) @@ -2544,25 +3079,54 @@ DrawItem( gc, topItem, ERemoveHighlight ); DrawItem( gc, (bottomItem-1), ERemoveHighlight ); } + SetSelectedItem( aNewSelectedItem ); PrepareHighlightFrame(); if ( previousTopItem == topItem && aNewSelectedItem >= 0 ) { // then only previuosly and currently selected items should be redrawn - if ( iExtension->iHighlightedItem != KErrNotFound ) - { - DrawItem( gc, previousSelectedItem, ERemoveHighlight ); - } + DrawItem( gc, previousSelectedItem, ERemoveHighlight ); if ( !iExtension->iSctHighlighted ) { DrawItem( gc, aNewSelectedItem, EDrawHighlight ); } } - + else + { + TBool skipHighlight = EFalse; + if (iExtension && iExtension->iSct && aNewSelectedItem == 0 && + previousSelectedItem > 1) + { + skipHighlight = ETrue; + } + for( TInt i = topItem; iiGc->Deactivate(); + } +#endif // RD_UI_TRANSITION_EFFECTS_LIST DeactivateGc(); + + UpdateScrollBarThumbs(); + // Updating view position here prevents some flickering + iExtension->ViewPositionChanged( iExtension->iViewPosition ); + _AKNTRACE_FUNC_EXIT; } @@ -2572,15 +3136,177 @@ // void CEikMenuPane::PrepareGcForDrawingItems(CGraphicsContext& aGc) const { + // BIDI /* * get the fonts from the LAF! * Do we need to get them here? - nope - moved to DrawItem() */ - aGc.SetPenColor( iEikonEnv->ControlColor( EColorMenuPaneText, *this) ); +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( iExtension->iGc ); + if ( transApi ) + { + transApi->StartDrawing( MAknListBoxTfxInternal::EListNotSpecified ); + } +#endif + + aGc.SetPenColor(iEikonEnv->ControlColor( EColorMenuPaneText, *this) ); +#if defined(MENU_TEXTURED_BACKGROUND) + iEikonEnv->SetTexturedBrush( aGc ); +#else aGc.SetBrushStyle( CGraphicsContext::ESolidBrush ); aGc.SetBrushColor( iEikonEnv->ControlColor( EColorMenuPaneBackground,*this ) ); - } +#endif + +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + if ( transApi ) + { + transApi->StopDrawing(); + } +#endif + } + +#ifdef RD_UI_TRANSITION_EFFECTS_LIST +/** + * Iterate through the visible items in a menu and calculate minimum + * item margins that dont need drawing. + */ +void CEikMenuPaneExtension::CalcItemSize( MAknListBoxTfxInternal* transApi ) const + { + if ( transApi && iControl->iItemArray && iControl->iItemArray->Count() ) + { + TRect marginRect(TRect::EUninitialized); + const TInt index = 0; + + // Specifies whether the text should be moved to give some space for icon. + TInt hasIcon = iControl->MenuHasIcon() ? 1 : 0; + + TAknWindowLineLayout menuPane( AKN_LAYOUT_WINDOW_list_menu_pane( 0 , 0 ) ); + TAknWindowLineLayout singleMenuPane( + AKN_LAYOUT_WINDOW_list_single_popup_menu_pane( index ) ); + TAknTextLineLayout menuTextLayout( + AKN_LAYOUT_TEXT_List_pane_texts__menu_single__Line_1(0) ); + + TAknLayoutRect menuPaneRect; + TAknLayoutRect singleMenuPaneRect; + TAknLayoutText textRect; + + TBool hasCascade = EFalse; + TBool hasNonCascade = EFalse; + + // number of items in the whole menu + for(TInt i = 0; i < iControl->iItemArray->Count(); i++) + { + CEikMenuPaneItem* item = (*iControl->iItemArray)[i]; + + // true if a cascade symbol must be drawn (main menu only) + TBool cascade = item->iData.iCascadeId != 0; + + if ( cascade ) + { + if ( hasCascade ) + { + if ( hasNonCascade ) + { + break; + } + continue; + } + hasCascade = ETrue; + } + else + { + if ( hasNonCascade ) + { + if ( hasCascade ) + { + break; + } + continue; + } + hasNonCascade = ETrue; + } + + if ( !iControl->iOwner ) + { + TAknWindowLineLayout listScrollPaneLayout( + AknLayoutScalable_Avkon::listscroll_menu_pane(0).LayoutLine() ); + AdjustPopupLayoutData( listScrollPaneLayout ); + TAknLayoutRect listScrollPaneRect; + listScrollPaneRect.LayoutRect( iControl->Rect(), listScrollPaneLayout ); + + menuPane = AknLayoutScalable_Avkon::list_menu_pane( 0 ).LayoutLine(); + menuPaneRect.LayoutRect( listScrollPaneRect.Rect(), menuPane ); + + singleMenuPane = AknLayoutScalable_Avkon::list_single_pane_cp2( index ).LayoutLine(); + singleMenuPaneRect.LayoutRect( menuPaneRect.Rect(), singleMenuPane ); + + menuTextLayout = AknLayoutScalable_Avkon::list_single_pane_t1_cp2( cascade ? 3 : 0 ).LayoutLine(); + } + else // Submenu + { + TBool hasDoubleSpanScrollBar = EFalse; + if ( iControl->iOwner && iControl->iSBFrame && + iControl->iSBFrame->VScrollBarVisibility() ) + { + hasDoubleSpanScrollBar = ETrue; + } + TAknWindowLineLayout listScrollPaneLayout( AknLayoutScalable_Avkon::listscroll_popup_sub_pane().LayoutLine() ); + TAknLayoutRect listScrollPaneRect; + listScrollPaneRect.LayoutRect( iControl->Rect(), listScrollPaneLayout ); + + menuPane = AknLayoutScalable_Avkon::list_submenu_pane( !hasDoubleSpanScrollBar ).LayoutLine(); + menuPaneRect.LayoutRect( listScrollPaneRect.Rect(), menuPane ); + + singleMenuPane = AknLayoutScalable_Avkon::list_single_popup_submenu_pane( index ).LayoutLine(); + singleMenuPaneRect.LayoutRect( menuPaneRect.Rect(), singleMenuPane ); + + menuTextLayout = TAknTextLineLayout( AknLayoutScalable_Avkon::list_single_popup_submenu_pane_t1( hasIcon ).LayoutLine() ); + } + + textRect.LayoutText( singleMenuPaneRect.Rect(), menuTextLayout ); + if (marginRect == TRect::EUninitialized) + { + marginRect = textRect.TextRect(); + } + else + { + marginRect.BoundingRect(textRect.TextRect()); + } + + if ( cascade ) + { + TAknWindowLineLayout elementCascade( AknLayoutScalable_Avkon::list_single_pane_cp2_g3().LayoutLine()); + TAknLayoutRect cascadeRect; + cascadeRect.LayoutRect( singleMenuPaneRect.Rect(), elementCascade ); + marginRect.BoundingRect(cascadeRect.Rect()); + } + else + { + TAknLayoutRect activeApplicationsIconRect; + activeApplicationsIconRect.LayoutRect( singleMenuPaneRect.Rect(), + AknLayoutScalable_Avkon::list_single_pane_g1_cp2(0).LayoutLine() ); + marginRect.BoundingRect(activeApplicationsIconRect.Rect()); + } + } + + if ( hasIcon ) + { + TAknLayoutRect iconLayoutRect; + iconLayoutRect.LayoutRect( singleMenuPaneRect.Rect(), + AknLayoutScalable_Avkon::list_single_popup_submenu_pane_g1().LayoutLine() ); + marginRect.BoundingRect(iconLayoutRect.Rect()); + } + + //send margins to tfx + TPoint tl ( marginRect.iTl - menuPaneRect.Rect().iTl ); + transApi->SetPosition( MAknListBoxTfxInternal::EListTLMargin, tl ); + + TPoint br( singleMenuPaneRect.Rect().Size().AsPoint() - marginRect.iBr + menuPaneRect.Rect().iTl ); + transApi->SetPosition( MAknListBoxTfxInternal::EListBRMargin, br ); + } + } +#endif // --------------------------------------------------------------------------- @@ -2590,9 +3316,28 @@ void CEikMenuPane::DrawItem( TInt aItem, THighlightType aHighlight ) const { ActivateGc(); +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + MAknListBoxTfxInternal* transApi = + CAknListLoader::TfxApiInternal( iExtension->iGc ); + + if ( transApi ) + { + iExtension->iGc->Activate( *DrawableWindow() ); + } + + CWindowGc& gc = transApi ? *iExtension->iGc : SystemGc(); +#else CWindowGc& gc = SystemGc(); +#endif // RD_UI_TRANSITION_EFFECTS_LIST PrepareGcForDrawingItems( gc ); DrawItem( gc, aItem, aHighlight ); + +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + if ( transApi ) + { + iExtension->iGc->Deactivate(); + } +#endif // RD_UI_TRANSITION_EFFECTS_LIST DeactivateGc(); } @@ -2618,6 +3363,14 @@ return; } + // seem to have window owning control in correct place + TRect windowRect = Rect(); + + if ( !iOwner ) + { + windowRect.iBr.iY -= ( iExtension->iCba->Rect().Height() ); + } + CEikMenuPaneItem* item = (*iItemArray)[aItem]; // Max visible number of items in menu / submenu TInt maxNumberOfItems = NumberOfItemsThatFitInView(); @@ -2651,15 +3404,12 @@ index += itemLeftInBottom; } - TBool drawSeparator = !( ( index + topIndex ) == numItemsInArray - 1 ); - TBool drawPartialItem = EFalse; - + TBool drawPartialItem(EFalse); if ( index == maxNumberOfItems ) { // We have partial items to draw because of panning so there // is one more item to draw than normally. drawPartialItem = ETrue; - // There is no layout data for the extra item, so we used the one // above it. --index; @@ -2671,32 +3421,58 @@ return; // only interested in drawing visible items } - TAknTextLineLayout menuTextLayout; + // Collect all of the information from the Layout DLL. Initialise these + // variables with DUMMY data. Then replace it with menu/submenu data. + TAknWindowLineLayout menuPane( AKN_LAYOUT_WINDOW_list_menu_pane( 0 , 0 ) ); + TAknWindowLineLayout singleMenuPane( + AKN_LAYOUT_WINDOW_list_single_popup_menu_pane( index ) ); + TAknTextLineLayout menuTextLayout( + AKN_LAYOUT_TEXT_List_pane_texts__menu_single__Line_1(0) ); + TAknLayoutRect menuPaneRect; TAknLayoutRect singleMenuPaneRect; - if ( !iOwner ) // main menu - { - singleMenuPaneRect.LayoutRect( iExtension->iItemAreaRect, - AknLayoutScalable_Avkon::list_single_pane_cp2( index ).LayoutLine() ); - menuTextLayout = - AknLayoutScalable_Avkon::list_single_pane_t1_cp2( cascade ? 1 : 0 ).LayoutLine(); - } - else // submenu - { - singleMenuPaneRect.LayoutRect( iExtension->iItemAreaRect, - AknLayoutScalable_Avkon::list_single_popup_submenu_pane( index ).LayoutLine() ); - + if ( !iOwner ) + { + TAknWindowLineLayout listScrollPaneLayout( + AknLayoutScalable_Avkon::listscroll_menu_pane(0).LayoutLine() ); + if ( iExtension ) + { + iExtension->AdjustPopupLayoutData( listScrollPaneLayout ); + } + TAknLayoutRect listScrollPaneRect; + listScrollPaneRect.LayoutRect( windowRect, listScrollPaneLayout ); + + menuPane = AknLayoutScalable_Avkon::list_menu_pane( 0 ).LayoutLine(); + menuPaneRect.LayoutRect( listScrollPaneRect.Rect(), menuPane ); + + singleMenuPane = AknLayoutScalable_Avkon::list_single_pane_cp2( index ).LayoutLine(); + singleMenuPaneRect.LayoutRect( menuPaneRect.Rect(), singleMenuPane ); + + menuTextLayout = AknLayoutScalable_Avkon::list_single_pane_t1_cp2( cascade ? 3 : 0 ).LayoutLine(); + } + else // Submenu + { + TBool hasDoubleSpanScrollBar = EFalse; + if ( iSBFrame && iSBFrame->VScrollBarVisibility() ) + { + hasDoubleSpanScrollBar = ETrue; + } + + TAknWindowLineLayout listScrollPaneLayout( AknLayoutScalable_Avkon::listscroll_popup_sub_pane().LayoutLine() ); + TAknLayoutRect listScrollPaneRect; + listScrollPaneRect.LayoutRect( windowRect, listScrollPaneLayout ); + + menuPane = AknLayoutScalable_Avkon::list_submenu_pane( !hasDoubleSpanScrollBar ).LayoutLine(); + menuPaneRect.LayoutRect( listScrollPaneRect.Rect(), menuPane ); + + singleMenuPane = AknLayoutScalable_Avkon::list_single_popup_submenu_pane( index ).LayoutLine(); + singleMenuPaneRect.LayoutRect( menuPaneRect.Rect(), singleMenuPane ); + + menuTextLayout = TAknTextLineLayout( AknLayoutScalable_Avkon::list_single_popup_submenu_pane_t1( 0 ).LayoutLine() ); + if ( hasIcon ) { - menuTextLayout = - TAknTextLineLayout( - AknLayoutScalable_Avkon::list_single_popup_submenu_pane_t1( 1 ).LayoutLine() ); - } - else - { - menuTextLayout = - TAknTextLineLayout( - AknLayoutScalable_Avkon::list_single_popup_submenu_pane_t1( 0 ).LayoutLine() ); + menuTextLayout = TAknTextLineLayout( AknLayoutScalable_Avkon::list_single_popup_submenu_pane_t1( 1 ).LayoutLine() ); } } @@ -2716,17 +3492,21 @@ RWindow& window = Window(); - if ( &window && window.GetDrawRect() == TRect::EUninitialized ) - { + if ( &window && window.GetDrawRect() == TRect::EUninitialized ) + { +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + MAknListBoxTfxInternal* transApi = + CAknListLoader::TfxApiInternal( &aGc ); + drawingInitiated = transApi && !transApi->EffectsDisabled(); +#else drawingInitiated = EFalse; - } - - if ( !drawingInitiated && !iExtension->iFullRedraw ) - { - TRect drawRect( itemRect ); - drawRect.Intersection( iExtension->iItemAreaRect ); - window.Invalidate( drawRect ); - window.BeginRedraw( drawRect ); +#endif + } + + if ( !drawingInitiated ) + { + window.Invalidate( itemRect ); + window.BeginRedraw( itemRect ); } MAknsSkinInstance* skin = AknsUtils::SkinInstance(); @@ -2736,70 +3516,136 @@ cc = iExtension->iBgContext; } TBool background( ETrue ); - - aGc.SetBrushStyle( CGraphicsContext::ESolidBrush ); - aGc.SetBrushColor( singleMenuPaneRect.Color() ); - - // there can be partial items, so clip drawing on menu pane's item area - aGc.SetClippingRect( iExtension->iItemAreaRect ); - - if (!iExtension->iFullRedraw) - { - background = AknsDrawUtils::Background( - skin, cc, this, aGc, itemRect, - KAknsDrawParamNoClearUnderImage ); - } - - if ( !background ) - { +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + MAknListBoxTfxInternal *transApi = CAknListLoader::TfxApiInternal( &aGc ); + if ( transApi && !transApi->EffectsDisabled() ) + { + iExtension->iGc->Activate( *DrawableWindow() ); + } +#endif + +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + if ( !transApi || transApi->EffectsDisabled() ) + { +#endif aGc.SetBrushStyle( CGraphicsContext::ESolidBrush ); - aGc.SetPenStyle( CGraphicsContext::ENullPen ); - aGc.SetPenColor( singleMenuPaneRect.Color() ); - aGc.SetBrushColor( singleMenuPaneRect.Color() ); - aGc.DrawRect( itemRect ); - } + aGc.SetBrushColor( singleMenuPaneRect.Color() ); + + if(!iExtension->iFullRedraw) + { + background = AknsDrawUtils::Background( + skin, cc, this, aGc, itemRect, + KAknsDrawParamNoClearUnderImage ); + } + + if( !background ) + { + aGc.SetBrushStyle( CGraphicsContext::ESolidBrush ); + aGc.SetPenStyle( CGraphicsContext::ENullPen ); + aGc.SetPenColor( singleMenuPaneRect.Color() ); + aGc.SetBrushColor( singleMenuPaneRect.Color() ); + aGc.DrawRect( itemRect ); + } +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + } +#endif if ( !iExtension->HighlightEnabled() ) { aHighlight = ENoHighlight; } - + switch ( aHighlight ) { case EDrawHighlight : { if ( !iExtension->iSctHighlighted ) { - iExtension->iHighlightedItem = aItem; - - // Because of transparency, background must be drawn here as well - // (as frame may be see-through) - aGc.SetBrushStyle( CGraphicsContext::ESolidBrush ); - aGc.SetBrushColor( singleMenuPaneRect.Color() ); - - AknsDrawUtils::Background( - skin, cc, this, aGc, itemRect, - KAknsDrawParamNoClearUnderImage ); - - TAknLayoutRect highlightTopLeft; - TAknLayoutRect highlightBottomRight; - - highlightTopLeft.LayoutRect(itemRect, - SkinLayout::List_highlight_skin_placing__popup_windows__Line_2() ); - highlightBottomRight.LayoutRect(itemRect, - SkinLayout::List_highlight_skin_placing__popup_windows__Line_5() ); - TRect outerRect( highlightTopLeft.Rect().iTl, highlightBottomRight.Rect().iBr ); - TRect innerRect( highlightTopLeft.Rect().iBr, highlightBottomRight.Rect().iTl ); - - TBool drawOk = AknsDrawUtils::DrawFrame( skin, - aGc, - outerRect, - innerRect, - KAknsIIDQsnFrList, - KAknsIIDDefault ); - - // skinned highlight drawing has failed - if ( !drawOk ) +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + if ( transApi ) + { + // This will remove the old bitmap + transApi->Invalidate( MAknListBoxTfxInternal::EListHighlight ); + + transApi->BeginRedraw( MAknListBoxTfxInternal::EListHighlight, + itemRect ); + transApi->StartDrawing( MAknListBoxTfxInternal::EListHighlight ); + } +#endif + + // Partial items, so prevent drawing over the edge of menu pane +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + if ( !transApi || ( transApi && transApi->EffectsDisabled() ) ) + { + aGc.SetClippingRect(menuPaneRect.Rect()); + } +#else + aGc.SetClippingRect(menuPaneRect.Rect()); +#endif // RD_UI_TRANSITION_EFFECTS_LIST + + TBool drawOk = EFalse; + if( iExtension->iAnimation ) // Draw animated highlight + { +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + if ( transApi && transApi->VerifyKml() == KErrNone ) + { + Extension()->UseNoAnimation(); + } + else + { +#endif + TAknLayoutRect highlightTopLeft; + TAknLayoutRect highlightBottomRight; + + highlightTopLeft.LayoutRect( itemRect, + SkinLayout::List_highlight_skin_placing__popup_windows__Line_2() ); + highlightBottomRight.LayoutRect( itemRect, + SkinLayout::List_highlight_skin_placing__popup_windows__Line_5() ); + + TRect outerRect( highlightTopLeft.Rect().iTl, highlightBottomRight.Rect().iBr ); + + drawOk = iExtension->iAnimation->Render( aGc, outerRect ); +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + } +#endif + } + + if( !drawOk ) + { + // Animated highlight was not available, use normal skinned + // rendering. + + // Because of transparency, background must be drawn here as well + // (as frame may be see-through) + aGc.SetBrushStyle( CGraphicsContext::ESolidBrush ); + aGc.SetBrushColor( singleMenuPaneRect.Color() ); + + AknsDrawUtils::Background( + skin, cc, this, aGc, itemRect, + KAknsDrawParamNoClearUnderImage ); + + TAknLayoutRect highlightTopLeft; + TAknLayoutRect highlightBottomRight; + + highlightTopLeft.LayoutRect(itemRect, + SkinLayout::List_highlight_skin_placing__popup_windows__Line_2() ); + highlightBottomRight.LayoutRect(itemRect, + SkinLayout::List_highlight_skin_placing__popup_windows__Line_5() ); + TRect outerRect( highlightTopLeft.Rect().iTl, highlightBottomRight.Rect().iBr ); + TRect innerRect( highlightTopLeft.Rect().iBr, highlightBottomRight.Rect().iTl ); + + drawOk = AknsDrawUtils::DrawFrame( skin, + aGc, + outerRect, + innerRect, + KAknsIIDQsnFrList, + KAknsIIDDefault ); + + } + + // Both animated highlight and normal highlight drawing have + // failed. + if( !drawOk ) { TAknLayoutRect shadowRect; TAknLayoutRect highlightRect; @@ -2811,18 +3657,41 @@ shadowRect.DrawRect( aGc ); highlightRect.DrawRect( aGc ); } + + aGc.CancelClippingRect(); + +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + if ( transApi ) + { + transApi->StopDrawing(); + transApi->EndRedraw( MAknListBoxTfxInternal::EListHighlight ); + } +#endif } break; } case ERemoveHighlight: case ENoHighlight: - if ( iExtension->iHighlightedItem == aItem ) - { - iExtension->iHighlightedItem = KErrNotFound; - } default: break; } +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + if ( transApi ) + { + transApi->BeginRedraw( MAknListBoxTfxInternal::EListItem, itemRect, aItem ); + transApi->StartDrawing( MAknListBoxTfxInternal::EListItem ); + } +#endif // RD_UI_TRANSITION_EFFECTS_LIST + + // Partial items, so prevent drawing over the edge of menu pane +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + if ( !transApi || ( transApi && transApi->EffectsDisabled() ) ) + { + aGc.SetClippingRect(menuPaneRect.Rect()); + } +#else + aGc.SetClippingRect(menuPaneRect.Rect()); +#endif // RD_UI_TRANSITION_EFFECTS_LIST // Cascade if ( cascade ) @@ -2835,18 +3704,13 @@ skin->GetCachedItemData( KAknsIIDQgnIndiSubmenu, EAknsITMaskedBitmap ) ); if( itemData ) { - AknIconUtils::SetSize( itemData->Bitmap(),cascadeRect.Rect().Size() ); aGc.BitBltMasked( cascadeRect.Rect().iTl, itemData->Bitmap(), cascadeRect.Rect().Size(), itemData->Mask(), ETrue ); } else { - if ( iExtension->iCascadeBitmap && iExtension->iCascadeBitmapMask ) - { - AknIconUtils::SetSize( iExtension->iCascadeBitmap,cascadeRect.Rect().Size() ); - aGc.BitBltMasked( cascadeRect.Rect().iTl, iExtension->iCascadeBitmap, - cascadeRect.Rect().Size(), iExtension->iCascadeBitmapMask, ETrue ); - } + aGc.BitBltMasked( cascadeRect.Rect().iTl, iExtension->iCascadeBitmap, + cascadeRect.Rect().Size(), iExtension->iCascadeBitmapMask, ETrue ); } } else @@ -2922,10 +3786,8 @@ } // Text - TAknLayoutText textRect; - textRect.LayoutText( itemRect, menuTextLayout ); + TAknLayoutText textRect( iExtension->GetMenuItemTextLayout( itemRect, cascade ) ); TRgb textColor = textRect.Color(); - if ( aHighlight == EDrawHighlight ) // highlighted text { AknsUtils::GetCachedColor( skin, textColor, KAknsIIDQsnTextColors, EAknsCIQsnTextColorsCG10 ); @@ -2957,6 +3819,7 @@ } aGc.SetBrushStyle( CGraphicsContext::ENullBrush ); aGc.SetPenColor( textColor ); + aGc.UseFont( textRect.Font() ); const CFont* font = textRect.Font(); @@ -2983,26 +3846,33 @@ iExtension->iCascadeDRect.SetRect( cascRect.iTl, cascRect.iBr ); } - TAknLayoutRect highlightRect; - highlightRect.LayoutRect( itemRect, - AKN_LAYOUT_WINDOW_Highlight_graphics__various__Line_2( itemRect ) ); - - // store the calculated y-position to the menu item, - // so that it can be used in HandlePointerEventL() - item->iPos = highlightRect.Rect().iTl.iY; - - // don't draw separator line for the last item - if ( drawSeparator ) - { - AknListUtils::DrawSeparator( aGc, itemRect, textColor, skin ); - } - - if ( !drawingInitiated && !iExtension->iFullRedraw ) + if(iExtension->iIsPenEnable) + { + TAknLayoutRect highlightRect; + highlightRect.LayoutRect( itemRect, + AKN_LAYOUT_WINDOW_Highlight_graphics__various__Line_2( itemRect ) ); + + // store the calculated y-position to the menu item, + // so that it can be used in HandlePointerEventL() + item->iPos = highlightRect.Rect().iTl.iY; + aGc.DiscardFont(); + } + + if ( !drawingInitiated ) { Window().EndRedraw(); } aGc.CancelClippingRect(); + +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + if ( transApi && !transApi->EffectsDisabled() ) + { + transApi->StopDrawing(); + transApi->EndRedraw( MAknListBoxTfxInternal::EListItem, aItem ); + iExtension->iGc->Deactivate(); + } +#endif // RD_UI_TRANSITION_EFFECTS_LIST } @@ -3010,8 +3880,36 @@ // CEikMenuPane::Draw // ----------------------------------------------------------------------------- // +#ifdef RD_UI_TRANSITION_EFFECTS_LIST EXPORT_C void CEikMenuPane::Draw( const TRect& aRect ) const { + CWindowGc& gc = ( iExtension && iExtension->iGc ) ? + *iExtension->iGc : SystemGc(); + MAknListBoxTfxInternal *transApi = CAknListLoader::TfxApiInternal( &gc ); + + if ( transApi ) + { + iExtension->iGc->Activate( *DrawableWindow() ); + + if ( !transApi->EffectsDisabled() ) + { + if ( iExtension->iScrollBarRect.iTl.iX <= aRect.iTl.iX && + iExtension->iScrollBarRect.iBr.iX >= aRect.iBr.iX ) + { + transApi->BeginRedraw( MAknListBoxTfxInternal::EListUpdateRect, aRect ); + iExtension->iGc->Deactivate(); + return; + } + + iExtension->CalcItemSize( transApi ); + } + } +#else +EXPORT_C void CEikMenuPane::Draw(const TRect& /*aRect*/) const + { +#endif // RD_UI_TRANSITION_EFFECTS_LIST + + TRect windowRect( Rect() ); MAknsSkinInstance* skin = AknsUtils::SkinInstance(); MAknsControlContext* cc = NULL; @@ -3020,11 +3918,37 @@ cc = iExtension->iBgContext; } +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + if ( transApi ) + { + transApi->SetListType( MAknListBoxTfxInternal::EListBoxTypeMenuPane ); + transApi->BeginRedraw( MAknListBoxTfxInternal::EListView, windowRect ); + } +#else CWindowGc& gc = SystemGc(); +#endif // RD_UI_TRANSITION_EFFECTS_LIST PrepareGcForDrawingItems( gc ); +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + if ( transApi ) + { + transApi->StartDrawing( MAknListBoxTfxInternal::EListView ); + } +#endif + + if ( !IsCascadeMenuPane() ) + { + CFbsBitmap* cbaExtension = AknsUtils::GetCachedBitmap( skin, KAknsIIDQsnBgSlicePopup ); + if ( cbaExtension ) + { + TAknLayoutRect sliceRect; + sliceRect.LayoutRect( windowRect, SkinLayout::Popup_windows_skin_placing__background_slice__Line_2() ); + AknIconUtils::SetSize( cbaExtension, sliceRect.Rect().Size() ); + gc.BitBlt( TPoint( windowRect.iTl.iX, windowRect.iBr.iY-cbaExtension->SizeInPixels().iHeight ), cbaExtension ); + windowRect.iBr.iY -=2; // two used as margin when rect layouts were done + } + } TInt count=0; - if( iItemArray ) { count=iItemArray->Count(); @@ -3033,37 +3957,97 @@ // Give the topmost menu item's rect to SCT if needed. if ( iExtension->iSct ) { - iExtension->iSct->SetMenuSctRect( ItemRect( 0 ) ); - + TAknLayoutRect listScrollPaneRect; + TAknLayoutRect menuPaneRect; + TAknLayoutRect singleMenuPaneRect; + + TAknWindowLineLayout listScrollPaneLayout( + AknLayoutScalable_Avkon::listscroll_menu_pane(0).LayoutLine() ); + if ( iExtension ) + { + iExtension->AdjustPopupLayoutData( listScrollPaneLayout ); + } + listScrollPaneRect.LayoutRect( windowRect, listScrollPaneLayout ); + menuPaneRect.LayoutRect( listScrollPaneRect.Rect(), + AknLayoutScalable_Avkon::list_menu_pane( 0 ).LayoutLine() ); + singleMenuPaneRect.LayoutRect( menuPaneRect.Rect(), + AknLayoutScalable_Avkon::list_single_pane_cp2( 0 ).LayoutLine() ); + // Give the rect of the first menu item to SCT. + iExtension->iSct->SetMenuSctRect( singleMenuPaneRect.Rect() ); +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + if( transApi ) + { + iExtension->iSctRect = singleMenuPaneRect.Rect(); + TAknLayoutRect cellLayRect; + cellLayRect.LayoutRect( iExtension->iSctRect, + AknLayoutScalable_Avkon::cell_graphic_popup_pane( 0, 0, 0 ) ); + iExtension->iSctRect.iTl.iX -= 1; + iExtension->iSctRect.iTl.iY -= 1; + iExtension->iSctRect.iBr.iX += 3; + transApi->ResetNonDrawingRects(); + transApi->AddNonDrawingRect( iExtension->iScrollBarRect ); + transApi->AddNonDrawingRect( iExtension->iSctRect ); + } +#endif // RD_UI_TRANSITION_EFFECTS_LIST + } + + if ( iExtension->iSct ) + { TRegionFix<4> region; - region.AddRect( aRect ); + region.AddRect( Rect() ); region.SubRect( iExtension->iSct->Rect() ); gc.SetClippingRegion( region ); } + TRect backgroundRect( iOwner ? windowRect : iExtension->GetBackgroundRect( windowRect ) ); + // The added flag removes the white bg for transparency TBool frameDrawn = AknsDrawUtils::Background( - skin, cc, this, gc, aRect, KAknsDrawParamNoClearUnderImage ); - - if ( aRect.Intersects( iExtension->iItemAreaRect ) ) - { - iExtension->iFullRedraw = ETrue; - - for ( TInt ii=0;iiiSctHighlighted && ii == iSelectedItem ) - DrawItem( gc, ii, EDrawHighlight); - else - DrawItem( gc, ii, ENoHighlight); - } - - iExtension->iFullRedraw = EFalse; - } + skin, cc, this, gc, backgroundRect, KAknsDrawParamNoClearUnderImage ); + +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + if ( transApi ) + { + transApi->StopDrawing(); + } +#endif // RD_UI_TRANSITION_EFFECTS_LIST + + iExtension->iFullRedraw = ETrue; + + for ( TInt ii=0;iiiSctHighlighted && ii == iSelectedItem ) + DrawItem( gc, ii, EDrawHighlight); + else + DrawItem( gc, ii, ENoHighlight); + } + + iExtension->iFullRedraw = EFalse; if ( iExtension->iSct ) { +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + if ( transApi ) + { + transApi->StartDrawing( MAknListBoxTfxInternal::EListNotSpecified ); + } +#endif gc.CancelClippingRegion(); - } +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + if ( transApi ) + { + transApi->StopDrawing(); + } +#endif + } + +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + if ( transApi ) + { + transApi->EndViewRedraw( aRect ); + iExtension->iGc->Deactivate(); + } +#endif // RD_UI_TRANSITION_EFFECTS_LIST } @@ -3137,38 +4121,11 @@ CEikMenuPane* menu = iOwner ? iOwner : this; MCoeControlObserver* observer = menu->Observer(); - if ( commandId >= EAknCmdMarkingModeEnter - && commandId <= EAknCmdMarkingModeUnmarkAll ) - { - CEikMenuBar* menuBar = static_cast( Parent() ); - if ( menuBar && menuBar->MenuPane() == this ) - { - static_cast( - menuBar)->ProcessCommandL( commandId ); - } - ReportCanceled(); - } - else if ( commandId != EAknCmdTaskSwapper ) + + if ( commandId != EAknCmdTaskSwapper ) { _AKNTRACE( "commandId = %d", commandId ); - TBool isDeleted = EFalse; - iIsDeleted = &isDeleted; - - CleanupStack::PushL( TCleanupItem( CleanLocalRef, this ) ); iMenuObserver->ProcessCommandL( commandId ); - CleanupStack::Pop(); - - if ( !isDeleted ) - { - CEikMenuBar* menuBar = static_cast( Parent() ); - if ( menuBar && menuBar->MenuPane() == this ) - { - static_cast( - menuBar)->ProcessCommandL( commandId ); - } - } - - iIsDeleted = NULL; } else { @@ -3202,6 +4159,26 @@ { _AKNTRACE_FUNC_ENTER; _AKNTRACE( "aDrawNow = %d", aDrawNow ); + if( iExtension ) + { + if ( IsFocused() ) + { +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + // Focus must be handled here, otherwise it will come to late + MAknListBoxTfxInternal *transApi = CAknListLoader::TfxApiInternal( iExtension->iGc ); + + if ( transApi ) + { + transApi->HandleFocusChange( ETrue ); + } +#endif // RD_UI_TRANSITION_EFFECTS_LIST + iExtension->FocusGained(); + } + else // Not focused + { + iExtension->FocusLost(); + } + } if ( !iItemArray || iItemArray->Count() == 0 ) { @@ -3393,52 +4370,74 @@ TInt itemAfterLastItem = loopScrolling ? 0 : max; TInt itemAfterFirstItem = loopScrolling ? max : 0; - // Scroll highlighted item so that it becomes visible, - // if it is not visible before (scrolling with scroll bar - // can cause highlighted item to go out of screen) - TInt topItem = iScroller->TopItemIndex(); - TInt bottomItem = topItem + NumberOfItemsThatFitInView(); - - if ( iExtension->Offset() < 0 ) - { - // Extra bottom item when panning - bottomItem++; - } - - if( bottomItem > NumberOfItemsInPane() ) - { - bottomItem = NumberOfItemsInPane(); - } - _AKNTRACE( "topItem = %d,bottomItem = %d", topItem,bottomItem ); - - if ( aType != EEventKeyDown && iSelectedItem != ENothingSelected && - !(iExtension->iSctHighlighted && topItem == 0) && - (iSelectedItem < topItem || iSelectedItem > bottomItem - 1) ) - { - _AKNTRACE( "[%s]", "ScrollToMakeItemVisible(iSelectedItem);" ); - ScrollToMakeItemVisible(iSelectedItem); - - ActivateGc(); - CWindowGc& gc = SystemGc(); - PrepareGcForDrawingItems( gc ); - - // draw all items that are needed. - for( TInt i = 0; i < count; i++ ) - { - if( i == iSelectedItem && !iExtension->iSctHighlighted) +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + CWindowGc& gc = iExtension->iGc ? *iExtension->iGc : SystemGc(); + MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( &gc ); +#endif //RD_UI_TRANSITION_EFFECTS_LIST + + if(iExtension->iIsPenEnable) + { + _AKNTRACE( "[%s]", "iExtension->iIsPenEnable = TRUE" ); + // Scroll highlighted item so that it becomes visible, + // if it is not visible before (scrolling with scroll bar + // can cause highlighted item to go out of screen) + TInt topItem = iScroller->TopItemIndex(); + TInt bottomItem = topItem + NumberOfItemsThatFitInView(); + + if ( iExtension->Offset() < 0 ) + { + // Extra bottom item when panning + bottomItem++; + } + + if( bottomItem > NumberOfItemsInPane() ) + { + bottomItem = NumberOfItemsInPane(); + } + _AKNTRACE( "topItem = %d,bottomItem = %d", topItem,bottomItem ); + + if ( aType != EEventKeyDown && iSelectedItem != ENothingSelected && + !(iExtension->iSctHighlighted && topItem == 0) && + (iSelectedItem < topItem || iSelectedItem > bottomItem - 1) ) + { + _AKNTRACE( "[%s]", "ScrollToMakeItemVisible(iSelectedItem);" ); + ScrollToMakeItemVisible(iSelectedItem); + + ActivateGc(); +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + if ( transApi ) { - DrawItem( gc, i, EDrawHighlight ); - } - else - { - DrawItem( gc, i, ERemoveHighlight ); + iExtension->iGc->Activate( *DrawableWindow() ); } - } - - DeactivateGc(); - _AKNTRACE( "[%s]", "OfferKeyEventL return 9" ); - _AKNTRACE_FUNC_EXIT; - return EKeyWasConsumed; +#else + CWindowGc& gc = SystemGc(); +#endif // RD_UI_TRANSITION_EFFECTS_LIST + PrepareGcForDrawingItems( gc ); + + // draw all items that are needed. + for( TInt i = 0; i < count; i++ ) + { + if( i == iSelectedItem && !iExtension->iSctHighlighted) + { + DrawItem( gc, i, EDrawHighlight ); + } + else + { + DrawItem( gc, i, ERemoveHighlight ); + } + } + +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + if ( transApi ) + { + iExtension->iGc->Deactivate(); + } +#endif // RD_UI_TRANSITION_EFFECTS_LIST + DeactivateGc(); + _AKNTRACE( "[%s]", "OfferKeyEventL return 9" ); + _AKNTRACE_FUNC_EXIT; + return EKeyWasConsumed; + } } if ( iSelectedItem != ENothingSelected || iExtension->iSctHighlighted ) @@ -3455,6 +4454,13 @@ // loop scrolling always used in options menus case EKeyDownArrow: _AKNTRACE( "[%s]", "OfferKeyEventL(EKeyDownArrow)" ); +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + if ( transApi ) + { + transApi->SetMoveType( + MAknListBoxTfxInternal::EListMoveDown ); + } +#endif //RD_UI_TRANSITION_EFFECTS_LIST if ( iExtension->iSctHighlighted && iExtension->iSct ) { iExtension->iSctHighlighted = EFalse; @@ -3480,6 +4486,13 @@ break; case EKeyUpArrow: _AKNTRACE( "[%s]", "OfferKeyEventL(EKeyUpArrow)" ); +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + if ( transApi ) + { + transApi->SetMoveType( + MAknListBoxTfxInternal::EListMoveUp ); + } +#endif //RD_UI_TRANSITION_EFFECTS_LIST if ( iExtension->iSct && iSelectedItem == 0 && !iExtension->iSctHighlighted ) { @@ -3682,72 +4695,100 @@ TInt count( NumberOfItemsInPane() ); - // Scroll highlighted item so that it becomes visible - // if it is not visible before (scrolling with scroll bar - // can cause highlighted item to go out of screen). - TInt topItem( iScroller->TopItemIndex() ); - TInt bottomItem( topItem + NumberOfItemsThatFitInView() ); - if ( bottomItem > count ) - { - bottomItem = count; - } - - if ( iExtension->Offset() < 0 && - ( iSelectedItem == topItem || iSelectedItem == bottomItem ) ) - { - // Restoring offset with "simulated" ok key event. - iExtension->RestoreOffset( EKeyOK ); - } - else if ( iSelectedItem < topItem || - iSelectedItem > bottomItem - 1 ) - { - if ( count > iSelectedItem ) - { - if ( iExtension->iSctHighlighted && iExtension->iSct ) + if ( iExtension->iIsPenEnable ) + { + // Scroll highlighted item so that it becomes visible + // if it is not visible before (scrolling with scroll bar + // can cause highlighted item to go out of screen). + TInt topItem( iScroller->TopItemIndex() ); + TInt bottomItem( topItem + NumberOfItemsThatFitInView() ); + if ( bottomItem > count ) + { + bottomItem = count; + } + + if ( iExtension->Offset() < 0 && + ( iSelectedItem == topItem || iSelectedItem == bottomItem ) ) + { + // Restoring offset with "simulated" ok key event. + iExtension->RestoreOffset( EKeyOK ); + } + else if ( iSelectedItem < topItem || + iSelectedItem > bottomItem - 1 ) + { + if ( count > iSelectedItem ) { - TKeyEvent key; - key.iCode = EKeyOK; - key.iModifiers = 0; - - TKeyResponse keyResponse( EKeyWasNotConsumed ); - TEventCode type( EEventNull ); - keyResponse = iExtension->iSct->OfferKeyEventL( key, - type ); - if ( keyResponse == EKeyWasConsumed ) + if ( iExtension->iSctHighlighted && iExtension->iSct ) { - ReportSelectionMadeL(); + TKeyEvent key; + key.iCode = EKeyOK; + key.iModifiers = 0; + + TKeyResponse keyResponse( EKeyWasNotConsumed ); + TEventCode type( EEventNull ); + keyResponse = iExtension->iSct->OfferKeyEventL( key, + type ); + if ( keyResponse == EKeyWasConsumed ) + { + ReportSelectionMadeL(); + } + _AKNTRACE( "[%s]" "ActivateCurrentItemL return 2" ); + _AKNTRACE_FUNC_EXIT; + return; } - _AKNTRACE( "[%s]" "ActivateCurrentItemL return 2" ); - _AKNTRACE_FUNC_EXIT; - return; + } + + iExtension->isUpdateScrollDirectly = ETrue; + ScrollToMakeItemVisible( iSelectedItem ); + iExtension->isUpdateScrollDirectly = EFalse; + + ActivateGc(); + +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + + MAknListBoxTfxInternal *transApi = + CAknListLoader::TfxApiInternal( iExtension->iGc ); + if ( transApi ) + { + iExtension->iGc->Activate( *DrawableWindow() ); } - } - - iExtension->isUpdateScrollDirectly = ETrue; - ScrollToMakeItemVisible( iSelectedItem ); - iExtension->isUpdateScrollDirectly = EFalse; - - ActivateGc(); - CWindowGc& gc = SystemGc(); - PrepareGcForDrawingItems( gc ); - - // Draw all items that are needed. - for ( TInt i = 0; i < count; i++ ) - { - if ( i == iSelectedItem && !iExtension->iSctHighlighted ) + CWindowGc& gc = transApi ? *iExtension->iGc : SystemGc(); + +#else + + CWindowGc& gc = SystemGc(); + +#endif // RD_UI_TRANSITION_EFFECTS_LIST + + PrepareGcForDrawingItems( gc ); + + // Draw all items that are needed. + for ( TInt i = 0; i < count; i++ ) { - DrawItem( gc, i, EDrawHighlight ); - } - else - { - DrawItem( gc, i, ERemoveHighlight ); + if ( i == iSelectedItem && !iExtension->iSctHighlighted ) + { + DrawItem( gc, i, EDrawHighlight ); + } + else + { + DrawItem( gc, i, ERemoveHighlight ); + } } - } - - DeactivateGc(); - _AKNTRACE( "[%s]" "ActivateCurrentItemL return 3" ); - _AKNTRACE_FUNC_EXIT; - return; + +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + + if ( transApi ) + { + iExtension->iGc->Deactivate(); + } + +#endif // RD_UI_TRANSITION_EFFECTS_LIST + + DeactivateGc(); + _AKNTRACE( "[%s]" "ActivateCurrentItemL return 3" ); + _AKNTRACE_FUNC_EXIT; + return; + } } if ( iCascadeMenuPane ) @@ -3832,7 +4873,7 @@ { TPointerEvent ptrEvent; ptrEvent.iType = TPointerEvent::EButton1Up; - TRAP_IGNORE( menubar->HandlePointerEventL( ptrEvent ) ); + menubar->HandlePointerEventL( ptrEvent ); } else { @@ -3868,6 +4909,11 @@ // EXPORT_C void CEikMenuPane::HandlePointerEventL( const TPointerEvent& aPointerEvent ) { + if( !AknLayoutUtils::PenEnabled() ) + { + return; + } + _AKNTRACE_FUNC_ENTER; if ( iOwner && !IsVisible() ) @@ -3903,28 +4949,19 @@ { if ( aPointerEvent.iType == TPointerEvent::EButton1Down ) { - if ( CAknTransitionUtils::TransitionsEnabled( AknTransEffect::EComponentTransitionsOff ) ) + if( AknLayoutUtils::PenEnabled() ) { - iExtension->ImmediateFeedback( ETouchFeedbackSubMenuClosed ); - } - else - { - iExtension->ImmediateFeedback( ETouchFeedbackPopUp ); + if ( CAknTransitionUtils::TransitionsEnabled( AknTransEffect::EComponentTransitionsOff ) ) + { + iExtension->ImmediateFeedback( ETouchFeedbackPopupClose ); + } + else + { + iExtension->ImmediateFeedback( ETouchFeedbackPopUp ); + } } iExtension->iShowCascadeTransition = ETrue; CloseCascadeMenu(); - // Submenu of submenu was closed - if ( iCascadeMenuPane ) - { - iCascadeMenuPane->iExtension->EnableHighlight( EFalse ); - iCascadeMenuPane->RepaintHighlight(); - iExtension->iDownOnMenuArea = EFalse; - } - else - { - iExtension->EnableHighlight( EFalse ); - RepaintHighlight(); - } IgnoreEventsUntilNextPointerUp(); _AKNTRACE( "[%s]", "HandlePointerEventL return 2" ); _AKNTRACE_FUNC_EXIT; @@ -4011,7 +5048,21 @@ // Get the option item's rect in Menu SCT if ( iExtension->iSct ) { - menuSctRect = iExtension->iItemAreaRect; + TAknLayoutRect menuPaneRect; + TAknWindowLineLayout menuPane; + + TAknWindowLineLayout listScrollPaneLayout( + AknLayoutScalable_Avkon::listscroll_menu_pane(0).LayoutLine() ); + if ( iExtension ) + { + iExtension->AdjustPopupLayoutData( listScrollPaneLayout ); + } + TAknLayoutRect listScrollPaneRect; + listScrollPaneRect.LayoutRect( Rect(), listScrollPaneLayout ); + + menuPane = AknLayoutScalable_Avkon::list_menu_pane( 0 ).LayoutLine(); + menuPaneRect.LayoutRect( listScrollPaneRect.Rect(), menuPane ); + menuSctRect = menuPaneRect.Rect(); } TRect cascadeMenuRect(0,0,0,0); @@ -4038,8 +5089,8 @@ // if submenu, then move it's rect coordinates to relative to parent. if ( iCascadeMenuPane ) { - TPoint subPos = iCascadeMenuPane->Position(); - cascadeMenuRect = TRect(subPos-Position(), iCascadeMenuPane->Size()); + TPoint subPos = iCascadeMenuPane->PositionRelativeToScreen(); + cascadeMenuRect = TRect(subPos-PositionRelativeToScreen(), iCascadeMenuPane->Size()); } // Pointerevent in case we need to pass event from submenu to parent @@ -4052,6 +5103,12 @@ iExtension->ResetPressedHighlight(); } +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + MAknListBoxTfxInternal *transApi = CAknListLoader::TfxApiInternal( + iExtension->iGc ); + TBool effects = transApi && !transApi->EffectsDisabled(); +#endif + switch (aPointerEvent.iType ) { case TPointerEvent::EButton1Up: @@ -4059,17 +5116,12 @@ _AKNTRACE( "[%s]", "TPointerEvent::EButton1Up" ); if ( !innerRect.Contains( aPointerEvent.iPosition ) ) { - TBool highlightWasEnabled = iExtension->HighlightEnabled(); // remove highlight in case highlight is outside of menu pane iExtension->EnableHighlight( EFalse ); if ( iOwner ) { RepaintHighlight(); } - else if ( highlightWasEnabled && !iCascadeMenuPane ) - { - DrawItem( SelectedItem(), ENoHighlight ); - } } if ( iOwner && !innerRect.Contains( aPointerEvent.iPosition ) && @@ -4080,10 +5132,10 @@ _AKNTRACE_FUNC_EXIT; return iOwner->HandlePointerEventL( parentEvent ); } + iExtension->iDownOnMenuArea = EFalse; iExtension->iPanningActive = EFalse; - if ( !(iExtension->iSct && iExtension->iSct->Rect().Contains( iExtension->iStartPoint ) ) - && iExtension->iDownOnMenuArea ) + if ( !(iExtension->iSct && iExtension->iSct->Rect().Contains( iExtension->iStartPoint ) ) ) { TPoint drag = iExtension->iStartPoint - aPointerEvent.iPosition; if ( iExtension->iPhysics->StartPhysics( @@ -4093,7 +5145,6 @@ iExtension->ResetPressedHighlight(); } } - iExtension->iDownOnMenuArea = EFalse; if ( iExtension->HighlightTimerActive() && !iExtension->iPressedDown ) { @@ -4174,7 +5225,7 @@ } else if ( iExtension->iButtonDownItem == iSelectedItem ) { - iExtension->ImmediateFeedback( ETouchFeedbackList, + iExtension->ImmediateFeedback( ETouchFeedbackBasicItem, ETouchFeedbackVibra ); if( !IsCascadeMenuPane() ) { @@ -4230,7 +5281,7 @@ { noSelection = ETrue; //when touch down during the flicking, play a basic list feedback - iExtension->ImmediateFeedback( ETouchFeedbackList ); + iExtension->ImmediateFeedback( ETouchFeedbackBasicItem ); } // stop physics for drag iExtension->iPhysics->StopPhysics(); @@ -4257,29 +5308,22 @@ // if submenu, and clicked outside of it if ( !cascadeMenuRect.Contains( aPointerEvent.iPosition ) ) { - if ( CAknTransitionUtils::TransitionsEnabled( AknTransEffect::EComponentTransitionsOff ) ) - { - iExtension->ImmediateFeedback( ETouchFeedbackSubMenuClosed ); - } - else - { - iExtension->ImmediateFeedback( ETouchFeedbackPopUp ); + if( AknLayoutUtils::PenEnabled() ) + { + if ( CAknTransitionUtils::TransitionsEnabled( AknTransEffect::EComponentTransitionsOff ) ) + { + iExtension->ImmediateFeedback( ETouchFeedbackPopupClose ); + } + else + { + iExtension->ImmediateFeedback( ETouchFeedbackPopUp ); + } } //Just close sub menu iExtension->iShowCascadeTransition = ETrue; CloseCascadeMenu(); - // Submenu of submenu was closed - if ( iCascadeMenuPane ) - { - iCascadeMenuPane->iExtension->EnableHighlight( EFalse ); - iCascadeMenuPane->RepaintHighlight(); - iExtension->iDownOnMenuArea = EFalse; - } - else - { - iExtension->EnableHighlight( EFalse ); - RepaintHighlight(); - } + iExtension->EnableHighlight( EFalse ); + RepaintHighlight(); IgnoreEventsUntilNextPointerUp(); break; } @@ -4312,12 +5356,18 @@ iExtension->iSct->HighlightSctRow( iExtension->iSctHighlighted ); } +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + if ( effects ) + { + transApi->SetMoveType( MAknListBoxTfxInternal::EListTap ); + } +#endif iExtension->iPressedDown = ETrue; // Start timer for pressed highlight if ( !noSelection ) { - iExtension->ImmediateFeedback( ETouchFeedbackList ); + iExtension->ImmediateFeedback( ETouchFeedbackBasicItem ); iExtension->StartHighlightTimerL(); } iExtension->iNextHighlightItem = ii; @@ -4326,13 +5376,18 @@ // down even on already highlighted item => list feedback if ( iExtension->iButtonDownItem == iSelectedItem ) { - iExtension->ImmediateFeedback( ETouchFeedbackList ); + iExtension->ImmediateFeedback( ETouchFeedbackBasicItem ); } if ( noSelection ) { iExtension->iButtonDownItem = KErrNotFound; } - +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + if ( effects ) + { + transApi->Draw( Rect() ); + } +#endif // if new item has submenu, show it if ( item->iData.iCascadeId ) { @@ -4351,7 +5406,6 @@ else { // Clicked out side submenu, parent handles this - iExtension->iDownOnMenuArea = EFalse; if ( iOwner ) { iExtension->CalculateParentEvent(aPointerEvent, parentEvent); @@ -4361,53 +5415,47 @@ } else { - // For finger usability, extend to the right. - TRect innerToRightRect; - if ( AknLayoutUtils::LayoutMirrored() ) - { - innerToRightRect = TRect( Rect().iTl, innerRect.iBr ); - } - else + if ( iExtension->iIsPenEnable ) { - innerToRightRect = TRect( innerRect.iTl, Rect().iBr ); + // For finger usability, extend to the right. + TRect innerToRightRect; + if ( AknLayoutUtils::LayoutMirrored() ) + { + innerToRightRect = TRect( Rect().iTl, innerRect.iBr ); + } + else + { + innerToRightRect = TRect( innerRect.iTl, Rect().iBr ); + } + // Keep opened + if ( innerToRightRect.Contains( aPointerEvent.iPosition ) ) + { + break; + } } - // Keep opened - if ( innerToRightRect.Contains( aPointerEvent.iPosition ) ) - { - break; - } - // clicked outside, then close menu case by case if ( iCascadeMenuPane ) { - if ( CAknTransitionUtils::TransitionsEnabled( AknTransEffect::EComponentTransitionsOff ) ) - { - iExtension->ImmediateFeedback( ETouchFeedbackSubMenuClosed ); - } - else - { - iExtension->ImmediateFeedback( ETouchFeedbackPopUp ); + if( AknLayoutUtils::PenEnabled() ) + { + if ( CAknTransitionUtils::TransitionsEnabled( AknTransEffect::EComponentTransitionsOff ) ) + { + iExtension->ImmediateFeedback( ETouchFeedbackPopupClose ); + } + else + { + iExtension->ImmediateFeedback( ETouchFeedbackPopUp ); + } } iExtension->iShowCascadeTransition = ETrue; CloseCascadeMenu(); //Just close sub menu. - // Submenu of submenu was closed - if ( iCascadeMenuPane ) - { - iCascadeMenuPane->iExtension->EnableHighlight( EFalse ); - iCascadeMenuPane->RepaintHighlight(); - } - else - { - iExtension->EnableHighlight( EFalse ); - RepaintHighlight(); - } + iExtension->EnableHighlight( EFalse ); + RepaintHighlight(); IgnoreEventsUntilNextPointerUp(); } else { - _AKNTRACE( "[%s]", "HandlePointerEventL return 12.5" ); - _AKNTRACE_FUNC_EXIT; - return; + ReportCanceled(); //Close main menu. } } } @@ -4439,17 +5487,25 @@ TPoint drag = iExtension->iStartPoint - aPointerEvent.iPosition; TInt threshold = drag.iY; - if( Abs( threshold ) > iExtension->iPhysics->DragThreshold() - && iExtension->iDownOnMenuArea ) + if( Abs( threshold ) > iExtension->iPhysics->DragThreshold() ) { - iExtension->EnableHighlight( EFalse ); iExtension->iButtonDownItem = KErrNotFound; iExtension->ResetPressedHighlight(); iExtension->iNextHighlightItem = KErrNotFound; iExtension->iPanningActive = ETrue; + iExtension->EnableHighlight( EFalse ); + +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + MAknListBoxTfx* tfxApi = CAknListLoader::TfxApi( iExtension->iGc ); + + if ( tfxApi ) + { + tfxApi->EnableEffects( EFalse ); + } +#endif // RD_UI_TRANSITION_EFFECTS_LIST } - if ( iExtension->iPanningActive && iExtension->iDownOnMenuArea ) + if ( iExtension->iPanningActive ) { TPoint delta( 0, iExtension->iPrevPoint.iY - aPointerEvent.iPosition.iY ); @@ -4468,8 +5524,7 @@ // act in Menu Sct or Option Menu repectively if (( iExtension->iSct && menuSctRect.Contains(aPointerEvent.iPosition)) || - ( !iExtension->iSct && innerRect.Contains(aPointerEvent.iPosition)) && - iExtension->iDownOnMenuArea ) + ( !iExtension->iSct && innerRect.Contains(aPointerEvent.iPosition))) { iExtension->iDraggedOutside = EFalse; // Scroll only through visible items @@ -4488,21 +5543,46 @@ && !cascadeMenuRect.Contains( aPointerEvent.iPosition ) ) { - if ( CAknTransitionUtils::TransitionsEnabled( - AknTransEffect::EComponentTransitionsOff ) ) + if ( AknLayoutUtils::PenEnabled() ) { - iExtension->ImmediateFeedback( - ETouchFeedbackSubMenuClosed ); - } - else - { - iExtension->ImmediateFeedback( - ETouchFeedbackPopUp ); + if ( CAknTransitionUtils::TransitionsEnabled( + AknTransEffect::EComponentTransitionsOff ) ) + { + iExtension->ImmediateFeedback( + ETouchFeedbackPopupClose ); + } + else + { + iExtension->ImmediateFeedback( + ETouchFeedbackPopUp ); + } } iExtension->iShowCascadeTransition = ETrue; CloseCascadeMenu(); } } + else + { + TInt oldSelected = iSelectedItem; + // update highlight to new item + if ( oldSelected != ii ) + { + iExtension->iPressedDown = EFalse; +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + if ( effects + && !iExtension->iShowCascadeTransition ) + { + transApi->SetMoveType( + MAknListBoxTfxInternal::EListDrag ); + } +#endif + } + TRect screenRect( TPoint( KMinTInt, KMinTInt ), + TPoint( KMaxTInt, KMaxTInt ) ); + TRect repeatRect( screenRect.iTl.iX, item->iPos, + screenRect.iBr.iX, item->iPos + + iItemHeight ); + } // item found, break break; } @@ -4738,6 +5818,9 @@ EXPORT_C void CEikMenuPane::SetSelectedItem( TInt aSelectedItem ) { iSelectedItem = (aSelectedItem >= NumberOfItemsInPane() ) ? 0 : aSelectedItem; + + if( iExtension ) + iExtension->ChangeHighlightBackground(); } // ----------------------------------------------------------------------------- @@ -4833,6 +5916,10 @@ void CEikMenuPane::HandleScrollEventL( CEikScrollBar* aScrollBar, TEikScrollEvent aEventType ) { _AKNTRACE_FUNC_ENTER; + if( !AknLayoutUtils::PenEnabled()) + { + return; + } _AKNTRACE( "[%s]", "Stop physics engine"); iExtension->iPhysics->StopPhysics(); @@ -4880,9 +5967,16 @@ // Items that becomes topmost and downmost items TInt newTopItem = 0; + // if update is not wanted, do nothing. if ( update ) { +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( + iExtension->iGc ); + TBool effects = transApi && !transApi->EffectsDisabled(); +#endif + switch (aEventType) { case EEikScrollUp: @@ -4944,7 +6038,17 @@ { _AKNTRACE( "[%s]", "EEikScrollPageDown"); _AKNTRACE( "bottomItem = %d", bottomItem); - update = ETrue; + // if last item is not visible + if ( bottomItem < countOfItems) + { + // move menu to show one site down or then downmost items. + newTopItem = (bottomItem <= (countOfItems - itemsThatFitToView)) ? (topItem + itemsThatFitToView) : (countOfItems - itemsThatFitToView); + } + else + { + update = EFalse; + } + _AKNTRACE( "newTopItem = %d", newTopItem); _AKNTRACE( "update = %d", update); } break; @@ -4952,35 +6056,80 @@ case EEikScrollThumbDragVert: { _AKNTRACE( "[%s]", "EEikScrollThumbDragVert"); +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + + if ( effects ) + { + MAknListBoxTfx* tfxApi = CAknListLoader::TfxApi( iExtension->iGc ); + + if ( tfxApi ) + { + tfxApi->EnableEffects( EFalse ); + effects = EFalse; + } + } +#endif // new thumb position TInt thumb = aScrollBar->ThumbPosition(); _AKNTRACE( "thumb = %d", thumb); - update = ETrue; + + // did dragging cause scrolling + if ( thumb != topItem ) + { + newTopItem = thumb; + } + else + { + update = EFalse; + } + _AKNTRACE( "newTopItem = %d", newTopItem); _AKNTRACE( "update = %d", update); } break; + case EEikScrollThumbReleaseVert: + { +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + MAknListBoxTfx* tfxApi = CAknListLoader::TfxApi( iExtension->iGc ); + + if ( tfxApi ) + { + tfxApi->EnableEffects( ETrue ); + } +#endif + } + return; + default: update = EFalse; break; } // if topItem changed, then draw menu again. - if ( newTopItem != topItem || update ) - { + if ( newTopItem != topItem ) + { +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + if ( effects ) + { + transApi->SetMoveType( newTopItem > topItem ? + MAknListBoxTfxInternal::EListScrollDown : + MAknListBoxTfxInternal::EListScrollUp ); + } +#endif + + iExtension->iListTopIndex = aScrollBar->ThumbPosition(); - TPoint newPosition( iExtension->iViewPosition.iX, - iExtension->iListTopIndex + iExtension->iViewHeight / 2 ); - - iExtension->iFlags.Set( CEikMenuPaneExtension::ESkipScrollbarUpdate ); - iExtension->ViewPositionChanged( newPosition ); - iExtension->iFlags.Clear( CEikMenuPaneExtension::ESkipScrollbarUpdate ); + + iExtension->iViewPosition.iY = + iExtension->iListTopIndex + iExtension->iViewHeight / 2; + + iExtension->ViewPositionChanged( iExtension->iViewPosition ); + } } _AKNTRACE_FUNC_EXIT; } - // ----------------------------------------------------------------------------- // CEikMenuPane::CreateScrollBarFrame // ----------------------------------------------------------------------------- @@ -4994,13 +6143,13 @@ { CEikScrollBarFrame::TScrollBarVisibility visibility = CEikScrollBarFrame::EOn; - if ( iItemArray->Count() <= NumberOfItemsThatFitInView() ) - { - // all items fit, no need to show the scrollbar + if ( iOwner && ( iItemArray->Count() <= NumberOfItemsThatFitInView() ) ) + { + // submenu with less than 6 items visibility = CEikScrollBarFrame::EOff; } - - TRAP_IGNORE( iSBFrame->SetScrollBarVisibilityL( CEikScrollBarFrame::EOff, visibility ) ); + TRAP_IGNORE( iSBFrame->SetScrollBarVisibilityL( CEikScrollBarFrame::EOff, visibility /*CEikScrollBarFrame::EAuto*/ ) ); + TRAP_IGNORE( iSBFrame->CreateDoubleSpanScrollBarsL( EFalse, EFalse, ETrue, EFalse ) ); iSBFrame->DrawBackground( EFalse, EFalse ); UpdateScrollBar(); @@ -5014,14 +6163,13 @@ // void CEikMenuPane::UpdateScrollBar() { - if ( !CheckCreateScroller() || !IsVisible() ) + if ( !CheckCreateScroller() ) return; CIdle* idle = iScroller->Idle(); if ( idle && !idle->IsActive() ) idle->Start( TCallBack( CEikMenuPane::UpdateScrollBarCallBackL, this ) ); } - // ----------------------------------------------------------------------------- // CEikMenuPane::UpdateScrollBarCallBackL // ----------------------------------------------------------------------------- @@ -5032,7 +6180,6 @@ return 0; } - // ----------------------------------------------------------------------------- // CEikMenuPane::DoUpdateScrollBarL // ----------------------------------------------------------------------------- @@ -5045,7 +6192,17 @@ TEikScrollBarModel hSbarModel; TEikScrollBarModel vSbarModel; - TRect clientRect( iExtension->iMenuPaneRect.Size() ); + TRect menuPaneRect; + if ( !iOwner ) + { + menuPaneRect = iExtension->iMenuPaneRect; + } + else + { + menuPaneRect = Rect(); + } + + TRect clientRect( menuPaneRect.Size() ); // Panning uses pixel resolution scrollbar vSbarModel.iThumbPosition = iExtension->iListTopIndex; @@ -5064,40 +6221,79 @@ layout.SetInclusiveMargin( 0 ); layout.iTilingMode = TEikScrollBarFrameLayout::EClientRectConstant; - CEikScrollBarFrame::TScrollBarVisibility visibility = - iSBFrame->ScrollBarVisibility( CEikScrollBar::EVertical ); - - // scrollbar is shown only if needed - if ( iExtension->iScrollbarVisibility == CEikScrollBarFrame::EOn - && visibility == CEikScrollBarFrame::EOff ) - { - iSBFrame->SetScrollBarVisibilityL( CEikScrollBarFrame::EOff, - CEikScrollBarFrame::EOn ); - iExtension->iScrollBarRect = iSBFrame->VerticalScrollBar()->Rect(); - } - else if ( iExtension->iScrollbarVisibility == CEikScrollBarFrame::EOff - && visibility == CEikScrollBarFrame::EOn ) - { - iSBFrame->SetScrollBarVisibilityL( CEikScrollBarFrame::EOff, - CEikScrollBarFrame::EOff ); - iExtension->iScrollBarRect = TRect::EUninitialized; - } - + // For main menupane scrollbar is always shown, for submenu only when needed + if ( !iOwner ) + { + iSBFrame->SetScrollBarVisibilityL( CEikScrollBarFrame::EOff, CEikScrollBarFrame::EOn ); + } + else + { + TInt maxItems = NumberOfItemsThatFitInView(); + TInt count = iItemArray->Count(); + iSBFrame->SetScrollBarVisibilityL( CEikScrollBarFrame::EOff, + (count > maxItems) ? CEikScrollBarFrame::EOn : CEikScrollBarFrame::EOff ); + } + TAknLayoutRect scrollLayoutRect; - scrollLayoutRect.LayoutRect( clientRect, - AknLayoutScalable_Avkon::listscroll_popup_sub_pane().LayoutLine() ); - scrollBarInclusiveRect = scrollLayoutRect.Rect(); - scrollBarClientRect = scrollBarInclusiveRect; - - AknLayoutUtils::LayoutVerticalScrollBar( iSBFrame, scrollBarClientRect, - AknLayoutScalable_Avkon::scroll_pane_cp4().LayoutLine()); + if ( !iOwner ) + { + TAknWindowLineLayout listScrollPaneLayout( + AknLayoutScalable_Avkon::listscroll_menu_pane(0).LayoutLine() ); + if ( iExtension ) + { + iExtension->AdjustPopupLayoutData( listScrollPaneLayout ); + } + scrollLayoutRect.LayoutRect( clientRect, listScrollPaneLayout ); + scrollBarInclusiveRect = scrollLayoutRect.Rect(); + scrollBarClientRect = scrollBarInclusiveRect; + + AknLayoutUtils::LayoutVerticalScrollBar( iSBFrame, scrollBarClientRect, + AknLayoutScalable_Avkon::scroll_pane_cp25(0).LayoutLine() ); + } + else + { + scrollLayoutRect.LayoutRect( clientRect, + AknLayoutScalable_Avkon::listscroll_popup_sub_pane().LayoutLine() ); + scrollBarInclusiveRect = scrollLayoutRect.Rect(); + scrollBarClientRect = scrollBarInclusiveRect; + + AknLayoutUtils::LayoutVerticalScrollBar( iSBFrame, scrollBarClientRect, + AknLayoutScalable_Avkon::scroll_pane_cp4().LayoutLine()); + } iSBFrame->TileL( &hDsSbarModel, &vDsSbarModel, scrollBarClientRect, scrollBarInclusiveRect, layout ); iSBFrame->SetVFocusPosToThumbPos( vDsSbarModel.FocusPosition() ); + +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( iExtension->iGc ); + if ( iSBFrame->VerticalScrollBar() && + iSBFrame->VScrollBarVisibility() == CEikScrollBarFrame::EOn ) + { + iExtension->iScrollBarRect = iSBFrame->VerticalScrollBar()->Rect(); + } + else + { + iExtension->iScrollBarRect = TRect::EUninitialized; + } + if ( transApi ) + { + transApi->ResetNonDrawingRects(); + transApi->AddNonDrawingRect( iExtension->iScrollBarRect ); + transApi->AddNonDrawingRect( iExtension->iSctRect ); + } +#endif // RD_UI_TRANSITION_EFFECTS_LIST + if ( iSBFrame->VerticalScrollBar() && + iSBFrame->VScrollBarVisibility() == CEikScrollBarFrame::EOn ) + { + iExtension->iSBRect = iSBFrame->VerticalScrollBar()->Rect(); + } + else + { + iExtension->iSBRect = TRect::EUninitialized; + } _AKNTRACE_FUNC_EXIT; } - // ----------------------------------------------------------------------------- // CEikMenuPane::UpdateScrollBarThumbs // ----------------------------------------------------------------------------- @@ -5110,7 +6306,6 @@ } } - // ----------------------------------------------------------------------------- // CEikMenuPane::ScrollToMakeItemVisible // ----------------------------------------------------------------------------- @@ -5158,14 +6353,13 @@ } else { - TRAP_IGNORE( DoUpdateScrollBarL() ); + DoUpdateScrollBarL(); } } _AKNTRACE_FUNC_EXIT; return; } - // ----------------------------------------------------------------------------- // CEikMenuPane::Scroll // ----------------------------------------------------------------------------- @@ -5194,13 +6388,13 @@ iScroller->SetTopItemIndex( newTop ); _AKNTRACE( "newTop = %d", newTop ); + // Menu moved with keys, update panning/flicking data iExtension->iListTopIndex = iScroller->TopItemIndex() * iItemHeight; - TPoint newPosition( iExtension->iViewPosition ); - newPosition.iY = iExtension->iListTopIndex + iExtension->iViewHeight / 2; + iExtension->iViewPosition.iY = + iExtension->iListTopIndex + iExtension->iViewHeight / 2; iExtension->SetOffset( 0 ); - iExtension->ViewPositionChanged( newPosition ); - + _AKNTRACE( "iExtension->iListTopIndex = %d", iExtension->iListTopIndex ); _AKNTRACE( "iExtension->iViewPosition.iY = %d", iExtension->iViewPosition.iY ); _AKNTRACE( "[%s]", "iExtension->SetOffset( 0 )" ); @@ -5209,7 +6403,6 @@ return; } - // ----------------------------------------------------------------------------- // CEikMenuPane::ViewRect // ----------------------------------------------------------------------------- @@ -5219,7 +6412,6 @@ return Rect(); } - // ----------------------------------------------------------------------------- // CEikMenuPane::NumberOfItemsThatFitInView // ----------------------------------------------------------------------------- @@ -5231,7 +6423,7 @@ { subst = 1; } - +#ifdef RD_UI_TRANSITION_EFFECTS_LIST iExtension->iItemsThatFitInView = iOwner ? AknLayoutScalable_Avkon:: list_single_popup_submenu_pane_ParamLimits().LastRow() + 1 : AknLayoutScalable_Avkon:: @@ -5242,9 +6434,20 @@ iExtension->iItemsThatFitInView --; } + if ( iExtension->iPhysics && iExtension->Offset() != 0 ) + { + // with kinetic scrolling there can be partial items on the screen + iExtension->iTotalNumberOfItemsInView = iExtension->iItemsThatFitInView + 1; + } + return iExtension->iItemsThatFitInView; - } - +#else + return iOwner ? AknLayoutScalable_Avkon:: + list_single_popup_submenu_pane_ParamLimits().LastRow() + 1 : + AknLayoutScalable_Avkon:: + list_single_pane_cp2_ParamLimits().LastRow() + 1 - subst; +#endif + } // ----------------------------------------------------------------------------- // CEikMenuPane::TotalItemHeight @@ -5283,7 +6486,6 @@ return err == KErrNone; } - // ----------------------------------------------------------------------------- // CEikMenuPane::CheckCreateScrollerL // ----------------------------------------------------------------------------- @@ -5394,6 +6596,27 @@ TRect rect( CalculateSizeAndPosition() ); SetExtent( rect.iTl, rect.Size() ); + TRAP_IGNORE( DoUpdateScrollBarL() ); + + UpdateBackgroundContext( Rect() ); + PrepareHighlightFrame(); + SetCascadedIconSize(); + + // Background under highlight may have changed -> we need to update + // highlight background to animation + if( iExtension ) + { + iExtension->HandleLayoutSwitch(); + } + +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + MAknListBoxTfxInternal *transApi = CAknListLoader::TfxApiInternal( iExtension->iGc ); + if ( transApi ) + { + transApi->Remove( MAknListBoxTfxInternal:: EListEverything ); + } +#endif + //Initialize physics engine if ( iExtension->iPhysics ) { @@ -5401,14 +6624,9 @@ iExtension->iListTopIndex = iScroller->TopItemIndex() * iItemHeight; iExtension->iViewPosition.iY = iExtension->iListTopIndex + iExtension->iViewHeight / 2; - } - - TRAP_IGNORE( DoUpdateScrollBarL() ); - - UpdateBackgroundContext( Rect() ); - PrepareHighlightFrame(); - SetCascadedIconSize(); - DrawDeferred(); + iExtension->ViewPositionChanged( iExtension->iViewPosition ); + } + if ( iCascadeMenuPane ) { iCascadeMenuPane->HandleResourceChange( aType ); @@ -5437,7 +6655,7 @@ pointerEvent.iType = TPointerEvent::EButton1Up; // Sending a up event to scroll bar for dehighlighting // the scroll bar. - TRAP_IGNORE ( verScrollBar->HandlePointerEventL(pointerEvent) ); + verScrollBar->HandlePointerEventL(pointerEvent); iSBFrame->DrawScrollBarsDeferred(); ClaimPointerGrab( EFalse ); } @@ -5456,11 +6674,7 @@ } else if ( aType == KAknMessageFocusLost ) { - if ( iCascadeMenuPane ) - { - iCascadeMenuPane->HandleResourceChange( aType ); - } - else if ( iExtension && iExtension->HighlightEnabled() ) + if ( iExtension && iExtension->HighlightEnabled() ) { iExtension->EnableHighlight( EFalse, EFalse ); DrawItem( iSelectedItem, ENoHighlight ); @@ -5732,17 +6946,14 @@ // it can be only in submenu in case when scalable layout is available TBool hasIcon = MenuHasIcon(); - - // scrollbar is shown only if needed - if ( iItemArray->Count() > NumberOfItemsThatFitInView() ) - { - iExtension->iScrollbarVisibility = CEikScrollBarFrame::EOn; - } - else - { - iExtension->iScrollbarVisibility = CEikScrollBarFrame::EOff; - } - + TBool hasDoubleSpanScrollBar = EFalse; + + if ( iSBFrame && iSBFrame->VScrollBarVisibility() ) + { + _AKNTRACE( "[%s]", "hasDoubleSpanScrollBar = ETrue;" ); + hasDoubleSpanScrollBar = ETrue; + } + TRect parentMenuRect; AknLayoutUtils::TAknCbaLocation cbaPosition = AknLayoutUtils::CbaLocation(); @@ -5834,6 +7045,8 @@ _AKNTRACE( "parentMenuRect.iTl.iY = %d", parentMenuRect.iTl.iY ); _AKNTRACE( "parentMenuRect.Width() = %d", parentMenuRect.Width() ); _AKNTRACE( "parentMenuRect.Height( = %d", parentMenuRect.Height() ); + // if we have landscape layout then main menu should be positioned vertically centered + TRect appRect( iEikonEnv->EikAppUi()->ApplicationRect() ); if ( !iOwner ) // main menu { @@ -5853,46 +7066,28 @@ // to be in correct place - so we calculate correct position for // background and move control rect to match new background top left // position. + TRect backgroundRect( iExtension->GetBackgroundRect( parentMenuRect ) ); TPoint backgroundRectPos( - AknPopupUtils::Position( parentMenuRect.Size(), ETrue ) ); + AknPopupUtils::Position( backgroundRect.Size(), ETrue ) ); retVal = parentMenuRect; - retVal.Move( backgroundRectPos - parentMenuRect.iTl ); + retVal.Move( backgroundRectPos - backgroundRect.iTl ); // Set embedded cba rect if ( iExtension->iCba ) { // There is hidden extra touch space for scroll bar in landscape - TInt xOffset = parentMenuRect.iTl.iX - parentMenuRect.iTl.iX ; + TInt xOffset = backgroundRect.iTl.iX - parentMenuRect.iTl.iX ; iExtension->iCba->SetRect( TRect( xOffset, menuRect.Height(), - parentMenuRect.Width() + xOffset, + backgroundRect.Width() + xOffset, menuRect.Height() + cbaRect.Rect().Height() ) ); } iExtension->iMenuPaneRect = TRect( retVal.iTl, TSize ( menuRect.Size() ) ); - - TInt variety = 4; - - // reserve area for scrollbar only if it's shown - if ( iExtension->iScrollbarVisibility == CEikScrollBarFrame::EOn ) - { - variety = 0; - } - - TAknLayoutRect layoutRect; - layoutRect.LayoutRect( TRect( iExtension->iMenuPaneRect.Size() ), - AknLayoutScalable_Avkon::listscroll_popup_sub_pane( 0 ) ); - - iExtension->iMenuAreaRect = layoutRect.Rect(); - - layoutRect.LayoutRect( iExtension->iMenuAreaRect, - AknLayoutScalable_Avkon::list_menu_pane( variety ) ); - - iExtension->iItemAreaRect = layoutRect.Rect(); - + _AKNTRACE( "[%s]", "the layout of main menu return" ); _AKNTRACE_FUNC_EXIT; return retVal; @@ -5905,13 +7100,20 @@ iExtension->iSubMenuWidthIndex = KAlternativeSubmenuWidths - 1; TAknLayoutRect parentListScrollLayoutRect; // listscroll_menu_pane + TAknLayoutRect parentPaneLayoutRect; // list_menu_pane TAknTextLineLayout subMenuText; // layout for the text when item is not indicated TAknTextLineLayout subMenuIconText; // layout for the text when item is indicated TAknWindowLineLayout parentListScrollPaneLayout( AknLayoutScalable_Avkon::listscroll_menu_pane(0).LayoutLine() ); + if ( iExtension ) + { + iExtension->AdjustPopupLayoutData( parentListScrollPaneLayout ); + } parentListScrollLayoutRect.LayoutRect( parentMenuRect, parentListScrollPaneLayout ); + parentPaneLayoutRect.LayoutRect( parentListScrollLayoutRect.Rect(), + AknLayoutScalable_Avkon::list_menu_pane(0).LayoutLine() ); subMenuText = AknLayoutScalable_Avkon::list_single_popup_submenu_pane_t1(0).LayoutLine(); subMenuIconText = AknLayoutScalable_Avkon::list_single_popup_submenu_pane_t1(1).LayoutLine(); @@ -5934,13 +7136,6 @@ } // find the suitable item width, so that the text would be visible - TInt submenuVariety = 1; - - if ( iExtension->iScrollbarVisibility == CEikScrollBarFrame::EOn ) - { - submenuVariety = 0; - } - for ( ii = 6; ii < KAlternativeSubmenuWidths + 6; ++ii ) { TAknWindowLineLayout submenuLayout( AknLayoutScalable_Avkon::popup_submenu_window( ii ).LayoutLine() ); @@ -5951,7 +7146,7 @@ TAknLayoutRect listScrollPaneRect; listScrollPaneRect.LayoutRect( submenuRect.Rect(), listScrollPaneLayout ); - TAknWindowLineLayout listSubmenuPaneLayout( AknLayoutScalable_Avkon::list_submenu_pane( submenuVariety ).LayoutLine() ); + TAknWindowLineLayout listSubmenuPaneLayout( AknLayoutScalable_Avkon::list_submenu_pane( !hasDoubleSpanScrollBar ).LayoutLine() ); TAknLayoutRect listSubmenuPaneRect; listSubmenuPaneRect.LayoutRect( listScrollPaneRect.Rect(), listSubmenuPaneLayout ); @@ -5983,8 +7178,20 @@ TInt parentPos = iOwner->iScroller->TopItemIndex() - iOwner->SelectedItem() + Min( parentCount, iOwner->NumberOfItemsThatFitInView() ); - TRect parentSelectedItemRect( iOwner->HighlightRect() ); - parentSelectedItemRect.Move( iOwner->Position() ); + TInt index = iOwner->SelectedItem() - iOwner->iScroller->TopItemIndex(); + TInt rows = AknLayoutScalable_Avkon::list_single_pane_cp2_ParamLimits().LastRow(); + + // This condition may be true if less items fits to menu view than sub-menu view + // and sub-menu under sub-menu is launched. + if (index > rows) + { + // Change the out-of-boundary index to last legal one. + index = rows; + } + + TAknLayoutRect parentSelectedItemRect; + parentSelectedItemRect.LayoutRect( parentPaneLayoutRect.Rect(), + AknLayoutScalable_Avkon::list_single_pane_cp2( index ).LayoutLine() ); TAknLayoutRect submenuWindowRect; // To prevent a panic in layout code, count has to be at least 1 even if @@ -6023,7 +7230,7 @@ if ( ( Layout_Meta_Data::IsLandscapeOrientation() && cbaPosition != AknLayoutUtils::EAknCbaLocationBottom ) ) { - if ( ( parentSelectedItemRect.iTl.iY + submenuWindowRect.Rect().Height() ) > + if ( ( parentSelectedItemRect.Rect().iTl.iY + submenuWindowRect.Rect().Height() ) > aWindowRect.iBr.iY ) { subMenuPos = EBottom; @@ -6075,7 +7282,7 @@ } else // floating { - TInt yPos = parentSelectedItemRect.iTl.iY - + TInt yPos = parentSelectedItemRect.Rect().iTl.iY - ( listScrollPaneRect.Rect().iTl.iY - submenuWindowRect.Rect().iTl.iY ); // When a submenu is floating, make sure that the possible panning offset of the @@ -6104,25 +7311,6 @@ retVal.Move( 0, -offset ); } } - - if ( retVal.iTl.iY < 0 ) - { - retVal.Move( 0, -retVal.iTl.iY ); - } - - iExtension->iMenuPaneRect = retVal; - - TAknLayoutRect layoutRect; - layoutRect.LayoutRect( TRect( iExtension->iMenuPaneRect.Size() ), - AknLayoutScalable_Avkon::listscroll_popup_sub_pane( 0 ) ); - - iExtension->iMenuAreaRect = layoutRect.Rect(); - - layoutRect.LayoutRect( iExtension->iMenuAreaRect, - AknLayoutScalable_Avkon::list_submenu_pane( submenuVariety ) ); - - iExtension->iItemAreaRect = layoutRect.Rect(); - _AKNTRACE( "[%s]", "the layout of sub menu return" ); _AKNTRACE_FUNC_EXIT; return retVal; @@ -6143,15 +7331,69 @@ if( index < 0 ) index = 0; + // It is possible that this method is called when iItemArray is NULL. In + // that case we fake numItems as 1 to make layout code work. + TInt maxItems = NumberOfItemsThatFitInView(); + TInt numItems = Min( Max( 1, iItemArray->Count() ), maxItems ); + if( !iItemArray ) + numItems = 1; + // When physics is enabled highlight can be moved to partially visible // item which is at the bottom of menu. This causes layout panic and to // avoid that we reduce index by one. - if ( index == NumberOfItemsThatFitInView() ) + if ( index == maxItems ) { index--; } - return ItemRect( index ); + TRect windowRect = Rect(); + + TAknWindowLineLayout menuPane( AKN_LAYOUT_WINDOW_list_menu_pane( 0 , 0 ) ); + TAknWindowLineLayout singleMenuPane( AKN_LAYOUT_WINDOW_list_single_popup_menu_pane( index ) ); + TAknLayoutRect menuPaneRect; + TAknLayoutRect singleMenuPaneRect; + + TBool hasDoubleSpanScrollBar = EFalse; + + if ( iSBFrame && iSBFrame->VScrollBarVisibility() ) + { + hasDoubleSpanScrollBar = ETrue; + } + + if ( !iOwner ) + { + TAknWindowLineLayout listScrollPaneLayout( + AknLayoutScalable_Avkon::listscroll_menu_pane(0).LayoutLine() ); + if ( iExtension ) + { + iExtension->AdjustPopupLayoutData( listScrollPaneLayout ); + } + TAknLayoutRect listScrollPaneRect; + listScrollPaneRect.LayoutRect( windowRect, listScrollPaneLayout ); + + menuPane = AknLayoutScalable_Avkon::list_menu_pane( 0 ).LayoutLine(); + menuPaneRect.LayoutRect( listScrollPaneRect.Rect(), menuPane ); + + singleMenuPane = AknLayoutScalable_Avkon::list_single_pane_cp2( index ).LayoutLine(); + singleMenuPaneRect.LayoutRect( menuPaneRect.Rect(), singleMenuPane ); + } + else // Submenu + { + TAknWindowLineLayout listScrollPaneLayout( AknLayoutScalable_Avkon::listscroll_popup_sub_pane().LayoutLine() ); + TAknLayoutRect listScrollPaneRect; + listScrollPaneRect.LayoutRect( windowRect, listScrollPaneLayout ); + + menuPane = AknLayoutScalable_Avkon::list_submenu_pane( !hasDoubleSpanScrollBar ).LayoutLine(); + menuPaneRect.LayoutRect( listScrollPaneRect.Rect(), menuPane ); + + singleMenuPane = AknLayoutScalable_Avkon::list_single_popup_submenu_pane( index ).LayoutLine(); + singleMenuPaneRect.LayoutRect( menuPaneRect.Rect(), singleMenuPane ); + } + + // Compared to normal DrawItem the highlight rect step is omitted because + // it would shift the highlight towards left. + + return singleMenuPaneRect.Rect(); } @@ -6197,6 +7439,7 @@ { AknIconUtils::SetSize( itemData->Bitmap(), cascadeRect.Rect().Size() ); } + else { if (iExtension->iCascadeBitmap) @@ -6239,7 +7482,8 @@ EXPORT_C TInt CEikMenuPane::CountComponentControls() const { TInt count = 0; - if ( iSBFrame && iSBFrame->VerticalScrollBar() ) + if ( iSBFrame && iSBFrame->VerticalScrollBar() && + !( iSBFrame->VerticalScrollBar()->OwnsWindow() ) ) { count = 1; } @@ -6266,7 +7510,8 @@ { case 0: { - if ( iSBFrame && iSBFrame->VerticalScrollBar() ) + if ( iSBFrame && iSBFrame->VerticalScrollBar() && + !( iSBFrame->VerticalScrollBar()->OwnsWindow() ) ) { return iSBFrame->VerticalScrollBar(); } @@ -6309,10 +7554,6 @@ } -// ----------------------------------------------------------------------------- -// CEikMenuPane::CheckCreateExtensionL -// ----------------------------------------------------------------------------- -// void CEikMenuPane::CheckCreateExtensionL() { if ( !iExtension ) @@ -6324,50 +7565,6 @@ // ----------------------------------------------------------------------------- -// CEikMenuPane::ItemRect -// ----------------------------------------------------------------------------- -// -TRect CEikMenuPane::ItemRect( TInt aItemIndex ) const - { - // this method is valid for the main menu only - TInt lastRow = AknLayoutScalable_Avkon::list_single_pane_cp2_ParamLimits().LastRow(); - aItemIndex = Min( aItemIndex, lastRow ); - - TAknLayoutRect layoutRect; - layoutRect.LayoutRect( iExtension->iItemAreaRect, - AknLayoutScalable_Avkon::list_single_pane_cp2( aItemIndex ) ); - - return layoutRect.Rect(); - } - - -// ----------------------------------------------------------------------------- -// CEikMenuPane::CalculateItemHeight -// ----------------------------------------------------------------------------- -// -TInt CEikMenuPane::CalculateItemHeight() const - { - TAknWindowLineLayout menuLineLayout; - - if ( iOwner ) // submenu - { - menuLineLayout = - AknLayoutScalable_Avkon::list_single_popup_submenu_pane( 0 ).LayoutLine(); - } - else - { - menuLineLayout = - AknLayoutScalable_Avkon::list_single_pane_cp2( 0 ).LayoutLine(); - } - - TAknLayoutRect menuLayoutRect; - menuLayoutRect.LayoutRect( Rect(), menuLineLayout ); - - return menuLayoutRect.Rect().Height(); - } - - -// ----------------------------------------------------------------------------- // CEikMenuPane::ConstructMenuSctRowL // Creates an sct row for editing menu. // @param aSpecialChars Buffer that holds selected characters @@ -6384,10 +7581,6 @@ { resourceId = R_AVKON_MENU_SCT_ROW_DEFAULT_CONTENTS_CHINESE; } - if (FeatureManager::FeatureSupported(KFeatureIdKorean)) - { - resourceId = R_AVKON_MENU_SCT_ROW_DEFAULT_CONTENTS_KOREAN; - } iExtension->ConstructMenuSctRowL( aSpecialChars, resourceId ); } @@ -6441,15 +7634,6 @@ EXPORT_C void CEikMenuPane::SetItemSpecific( TInt aCommandId, TBool aItemSpecific ) { - if ( !iExtension ) - { - TRAPD( err, CheckCreateExtensionL() ); - if ( err ) - { - return; - } - } - if ( iExtension->iFlags.IsSet( CEikMenuPaneExtension::ESingleClickEnabled ) ) { @@ -6528,20 +7712,30 @@ if ( iCascadeMenuPane->IsVisible() ) { okToDraw = AknsUtils::SkinInstance() != NULL; +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + MAknListBoxTfxInternal *transApi = CAknListLoader::TfxApiInternal( iExtension->iGc ); + if ( transApi && okToDraw ) + { + iCascadeMenuPane->SetFocus( EFalse, EDrawNow ); + } +#endif // Stop ongoing comp. transitions, this is mostly for fast clicking // cases to make sure that no "scrap" is left behind. GfxTransEffect::NotifyExternalState( ENotifyGlobalAbort ); - // cascade menu "cancel" animation. This does not apply // when something is chosen from the menu - if ( iExtension->iShowCascadeTransition && okToDraw ) - { - iCascadeMenuPane->SetParent( this ); - - GfxTransEffect::Begin( iCascadeMenuPane, KGfxControlDisappearAction ); - GfxTransEffect::SetDemarcation( iCascadeMenuPane, iExtension->iCascadeDRect ); - iCascadeMenuPane->MakeVisible( EFalse ); - GfxTransEffect::End( iCascadeMenuPane ); + + if( iExtension->iShowCascadeTransition && okToDraw ) + { + iCascadeMenuPane->SetParent( this ); + + GfxTransEffect::Begin( iCascadeMenuPane, KGfxControlDisappearAction ); + GfxTransEffect::SetDemarcation( iCascadeMenuPane, iExtension->iCascadeDRect ); + + iCascadeMenuPane->MakeVisible( EFalse ); + + GfxTransEffect::End( iCascadeMenuPane ); + } } @@ -6585,83 +7779,29 @@ // ----------------------------------------------------------------------------- -// CEikMenuPane::SetItemCommandsStateL -// ----------------------------------------------------------------------------- -// -void CEikMenuPane::SetItemCommandsStateL( TBool aDimmed ) +// CEikMenuPane::SetItemCommandsDimmed +// ----------------------------------------------------------------------------- +// +void CEikMenuPane::SetItemCommandsDimmed() { if ( iExtension && iExtension->iFlags.IsSet( CEikMenuPaneExtension::ESingleClickEnabled ) ) { - if ( aDimmed ) - { - iExtension->iFlags.Set( - CEikMenuPaneExtension::EHideItemSpecificCommands ); - } - else - { - iExtension->iFlags.Set( - CEikMenuPaneExtension::EHideViewSpecificCommands ); - } + iExtension->iFlags.Set( + CEikMenuPaneExtension::EHideItemSpecificCommands ); for ( TInt i = 0; i < iItemArray->Count(); ++i ) { CEikMenuPaneItem* item = iItemArray->At( i ); - TBool itemSpecificItem( - item->iData.iFlags & EEikMenuItemAction + if ( item->iData.iFlags & EEikMenuItemAction || item->iData.iFlags & EEikMenuItemSpecific - || item->iData.iFlags & EEikMenuItemSpecificListQuery ); - // Dim item specific items - if ( aDimmed && itemSpecificItem ) + || item->iData.iFlags & EEikMenuItemSpecificListQuery ) { item->iData.iFlags |= EEikMenuItemDimmed; } - // Dim items not item specific - else if ( !aDimmed - && ( !itemSpecificItem - || item->iData.iFlags & EEikMenuItemAction ) ) - { - item->iData.iFlags |= EEikMenuItemDimmed; - if ( item->iData.iCascadeId ) - { - // i is not updated in AddCascadeMenuItemsToMenuL so going - // through added items again here. Then it goes through - // also submenus of submenus. - AddCascadeMenuItemsToMenuL( - item->iData.iCascadeId, ETrue, EFalse, NULL, i ); - } - } - } - } - } - -// ----------------------------------------------------------------------------- -// CEikMenuPane::SetItemActionsStateL -// ----------------------------------------------------------------------------- -// -void CEikMenuPane::SetItemActionsStateL( TBool aDimmed ) - { - if ( iExtension && iExtension->iFlags.IsSet( - CEikMenuPaneExtension::ESingleClickEnabled ) ) - { - if ( aDimmed ) - { - iExtension->iFlags.Set( - CEikMenuPaneExtension::EHideItemActionCommands ); - } - - for ( TInt i = 0; i < iItemArray->Count(); ++i ) - { - CEikMenuPaneItem* item = iItemArray->At( i ); - TBool itemActionItem( - item->iData.iFlags & EEikMenuItemAction ); - // Dim item specific items - if ( aDimmed && itemActionItem ) - { - item->iData.iFlags |= EEikMenuItemDimmed; - } - } - } - } + } + } + } + // ----------------------------------------------------------------------------- // CEikMenuPane::AddMenuItemsToItemActionMenuL @@ -6685,8 +7825,8 @@ if ( !( item->iData.iFlags & EEikMenuItemSpecificListQuery ) && item->iData.iCascadeId ) { - AddCascadeMenuItemsToMenuL( - item->iData.iCascadeId, EFalse, ETrue, &aMenuData ); + AddCascadeMenuItemsToActionMenuL( + item->iData.iCascadeId, EFalse, aMenuData ); } // If menu item is list query or it does not have cascade menu else @@ -6702,23 +7842,21 @@ else if ( item->iData.iCascadeId && !( item->iData.iFlags & EEikMenuItemDimmed ) ) { - AddCascadeMenuItemsToMenuL( - item->iData.iCascadeId, ETrue, ETrue, &aMenuData ); - } - } - } - - -// ----------------------------------------------------------------------------- -// CEikMenuPane::AddCascadeMenuItemsToMenuL -// ----------------------------------------------------------------------------- -// -void CEikMenuPane::AddCascadeMenuItemsToMenuL( + AddCascadeMenuItemsToActionMenuL( + item->iData.iCascadeId, ETrue, aMenuData ); + } + } + } + + +// ----------------------------------------------------------------------------- +// CEikMenuPane::AddCascadeMenuItemsToActionMenuL +// ----------------------------------------------------------------------------- +// +void CEikMenuPane::AddCascadeMenuItemsToActionMenuL( TInt aCascadeId, TBool aItemSpecific, - TBool aAddToItemActionMenu, - CAknItemActionMenuData* aMenuData, - TInt aItemIndex ) + CAknItemActionMenuData& aMenuData ) { if ( aCascadeId && iCoeEnv->IsResourceAvailableL( aCascadeId ) ) { @@ -6737,17 +7875,10 @@ || ( !aItemSpecific && !( item->iData.iFlags & EEikMenuItemDimmed ) ) ) { - if ( aAddToItemActionMenu ) - { - aMenuData->AddMenuItemToDataArrayL( - item->iData.iCommandId, - item->iData.iCascadeId, - item->iData.iText ); - } - else - { - InsertMenuItemL( item->iData, ++aItemIndex ); - } + aMenuData.AddMenuItemToDataArrayL( + item->iData.iCommandId, + item->iData.iCascadeId, + item->iData.iText ); } } CleanupStack::PopAndDestroy( cascadeMenu ); @@ -6767,31 +7898,5 @@ } } -// ----------------------------------------------------------------------------- -// CEikMenuPane::HideMarkAndUnmark -// ----------------------------------------------------------------------------- -// -void CEikMenuPane::HideMarkAndUnmark( TBool aHide ) - { - if ( aHide ) - { - iExtension->iFlags.Set( CEikMenuPaneExtension::EHideMarkAndUnmark ); - } - else - { - iExtension->iFlags.Clear( CEikMenuPaneExtension::EHideMarkAndUnmark ); - } - } - -// ----------------------------------------------------------------------------- -// CEikMenuPane::CleanLocalRef -// ----------------------------------------------------------------------------- -// -void CEikMenuPane::CleanLocalRef( TAny* aParam ) - { - static_cast( aParam )->iIsDeleted = NULL; - } - - // end of file