--- a/uifw/EikStd/coctlsrc/aknstyluspopupmenu.cpp Tue Aug 31 15:28:30 2010 +0300
+++ b/uifw/EikStd/coctlsrc/aknstyluspopupmenu.cpp Wed Sep 01 12:16:19 2010 +0100
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
+* Copyright (c) 2005-2010 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"
@@ -24,7 +24,9 @@
#include <eikapp.h>
#include <aknappui.h>
#include <AknDef.h>
-
+#include <touchfeedback.h>
+#include <akntranseffect.h>
+#include <akntransitionutils.h>
#include "aknstyluspopupmenu.h"
#include "aknstyluspopupmenucontent.h"
@@ -44,11 +46,13 @@
//
CAknStylusPopUpMenu::CAknStylusPopUpMenu( MEikMenuObserver* aObserver,
const TPoint& aPoint,
- CAknPreviewPopUpController* aPopup )
+ CAknPreviewPopUpController* aPopup,
+ const TInt aFlags )
: iPosition ( aPoint ),
iMenuObserver( aObserver ),
iPreviewPopup( aPopup ),
- iPositionType( EPositionTypeLeftTop )
+ iPositionType( EPositionTypeLeftTop ),
+ iModeFlags ( aFlags )
{
}
@@ -81,6 +85,24 @@
return self;
}
+// ---------------------------------------------------------------------------
+// CAknStylusPopUpMenu::NewL
+// ---------------------------------------------------------------------------
+//
+CAknStylusPopUpMenu* CAknStylusPopUpMenu::NewL( MEikMenuObserver* aObserver,
+ const TPoint& aPoint,
+ CAknPreviewPopUpController* aPopup,
+ const TInt aFlags )
+ {
+ CAknStylusPopUpMenu* self = new ( ELeave ) CAknStylusPopUpMenu( aObserver,
+ aPoint,
+ aPopup,
+ aFlags );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+ return self;
+ }
// ---------------------------------------------------------------------------
// CAknStylusPopUpMenu::NewL
@@ -119,6 +141,10 @@
//
CAknStylusPopUpMenu::~CAknStylusPopUpMenu()
{
+ if ( iContent )
+ {
+ iContent->SetObserver(NULL);
+ }
if ( iIsDeleted )
{
*iIsDeleted = ETrue;
@@ -172,23 +198,56 @@
//
EXPORT_C void CAknStylusPopUpMenu::ShowMenu()
{
- TRAPD( err,
- iController = CAknPreviewPopUpController::NewL( *iContent,
- CAknPreviewPopUpController::ELayoutSubMenu |
- CAknPreviewPopUpController::EAutoMirror |
- CAknPreviewPopUpController::EDontClose ) );
- if ( err )
+ // if contoller exists, re-use it .
+ if ( !iController )
{
- return;
- }
+ TInt err ( KErrNone );
+
+ if ( iModeFlags & EConsumeKeyEvents )
+ {
+ TRAP( err, iController = CAknPreviewPopUpController::NewL(
+ *iContent,
+ CAknPreviewPopUpController::ELayoutSubMenu |
+ CAknPreviewPopUpController::EAutoMirror |
+ CAknPreviewPopUpController::EDontClose |
+ CAknPreviewPopUpController::EConsumeKeys ) );
+ }
+ else
+ {
+ TRAP( err, iController = CAknPreviewPopUpController::NewL(
+ *iContent,
+ CAknPreviewPopUpController::ELayoutSubMenu |
+ CAknPreviewPopUpController::EAutoMirror |
+ CAknPreviewPopUpController::EDontClose ) );
+ }
+ if ( err )
+ {
+ return;
+ }
- iController->SetPopUpShowDelay( KDefaultPopUpShowDelay );
- iController->SetPopUpHideDelay( KDefaultPopUpHideDelay );
- iContent->Parent()->DrawableWindow()->SetNonFading(ETrue);
+ iController->SetPopUpShowDelay( KDefaultPopUpShowDelay );
+ iController->SetPopUpHideDelay( KDefaultPopUpHideDelay );
+ }
TSize size(iController->Size());
iController->ShowPopUp();
-
+ if ( AknLayoutUtils::PenEnabled() )
+ {
+ MTouchFeedback* feedback = MTouchFeedback::Instance();
+ if ( feedback )
+ {
+ TTouchLogicalFeedback feedbackType = ETouchFeedbackPopUp;
+ if ( CAknTransitionUtils::TransitionsEnabled( AknTransEffect::EComponentTransitionsOff ) )
+ {
+ feedbackType = ETouchFeedbackOptionsMenuOpened;
+ }
+ feedback->InstantFeedback(
+ iContent,
+ feedbackType,
+ ETouchFeedbackVibra,
+ TPointerEvent() );
+ }
+ }
if ( size.iWidth == 0 && size.iHeight == 0 )
{
if ( iPositionType != KErrNotFound )
@@ -223,7 +282,8 @@
// CAknStylusPopUpMenu::SetPosition
// ---------------------------------------------------------------------------
//
-EXPORT_C void CAknStylusPopUpMenu::SetPosition( const TPoint& aPoint, TPositionType aPosType )
+EXPORT_C void CAknStylusPopUpMenu::SetPosition( const TPoint& aPoint,
+ TPositionType aPosType )
{
TPoint adjustedPoint( aPoint );
if ( !iController )
@@ -232,41 +292,106 @@
iPositionType = aPosType;
return;
}
+
iController->UpdateContentSize();
TSize menuSize = iController->Size();
- // calculate to right-top corner by aPosType and popup menu size
+
+ // Calculate the position to right-top corner by aPosType and
+ // popup menu size. Add also a margin between the screen borders and the
+ // popup if the popup is too close to screen border.
+ TBool layoutMirrored( AknLayoutUtils::LayoutMirrored() );
+ TRect screenRect;
+ AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EScreen,
+ screenRect );
+
+ // Margin is read from the popup window's layout data
+ // (left parameter used).
+ TAknWindowLineLayout popupWindowLayout(
+ AknLayoutScalable_Avkon::popup_touch_menu_window( 0 ).LayoutLine() );
+ TInt windowMargin = layoutMirrored ? popupWindowLayout.ir :
+ popupWindowLayout.il;
+
switch ( aPosType )
{
- case EPositionTypeRightTop:
+ case EPositionTypeRightTop:
+ {
break;
+ }
+
case EPositionTypeLeftTop:
- if( AknLayoutUtils::LayoutMirrored() )
+ {
+ if ( !layoutMirrored )
{
- adjustedPoint.iX -= menuSize.iWidth;
+ adjustedPoint.iX += menuSize.iWidth;
}
- else
+
+ break;
+ }
+
+ case EPositionTypeRightBottom:
+ {
+ adjustedPoint.iY -= menuSize.iHeight;
+
+ break;
+ }
+
+ case EPositionTypeLeftBottom:
+ {
+ if ( !layoutMirrored )
{
adjustedPoint.iX += menuSize.iWidth;
}
- break;
- case EPositionTypeRightBottom:
+
adjustedPoint.iY -= menuSize.iHeight;
+
+ break;
+ }
+
+ default:
+ {
break;
- case EPositionTypeLeftBottom:
- if( AknLayoutUtils::LayoutMirrored() )
- {
- adjustedPoint.iX -= menuSize.iWidth;
- }
- else
- {
- adjustedPoint.iX += menuSize.iWidth;
- }
- adjustedPoint.iY -= menuSize.iHeight;
- break;
- default:
- break;
+ }
+ }
+
+ // Check if margins need to be added.
+ TInt xLeftPos( layoutMirrored ? adjustedPoint.iX :
+ adjustedPoint.iX - menuSize.iWidth );
+ TInt xRightPos( layoutMirrored ? adjustedPoint.iX + menuSize.iWidth :
+ adjustedPoint.iX );
+ TInt xPosRightMargin( screenRect.iBr.iX - windowMargin );
+ TInt xPosBottomMargin( screenRect.iBr.iY - windowMargin );
+
+ if ( xLeftPos < windowMargin )
+ {
+ // Too close to the left side of the screen.
+ adjustedPoint.iX = windowMargin + menuSize.iWidth;
+ }
+ else if ( xRightPos > xPosRightMargin )
+ {
+ // Too close to the right side of the screen.
+ if ( layoutMirrored )
+ {
+ // In mirrored layout a left-top position must be provided
+ // for the preview popup controller.
+ adjustedPoint.iX = xPosRightMargin - menuSize.iWidth;
+ }
+ else
+ {
+ adjustedPoint.iX = xPosRightMargin;
+ }
+ }
+
+ if ( adjustedPoint.iY < windowMargin )
+ {
+ // Too close to the top border of the screen.
+ adjustedPoint.iY = windowMargin;
+ }
+ else if ( adjustedPoint.iY + menuSize.iHeight > xPosBottomMargin )
+ {
+ // Too close to the bottom border of the screen.
+ adjustedPoint.iY = xPosBottomMargin - menuSize.iHeight;
+ }
- }
iPosition = adjustedPoint;
iController->SetPosition( adjustedPoint );
}
@@ -312,19 +437,26 @@
if ( iMenuObserver )
{
+ TBool isAlreadySet = iFlags.IsSet( EIdleDisabled );
+
iFlags.Set( EIdleDisabled );
TBool isDeleted = EFalse;
iIsDeleted = &isDeleted;
+ CleanupStack::PushL( TCleanupItem( CleanLocalRef, this ) );
iMenuObserver->ProcessCommandL( iContent->CurrentCommandId() );
-
+ CleanupStack::Pop();
+
if ( isDeleted )
{
return;
}
iIsDeleted = NULL;
- iFlags.Clear( EIdleDisabled );
+ if( !isAlreadySet )
+ {
+ iFlags.Clear( EIdleDisabled );
+ }
}
StartControllerIdleL();
@@ -335,6 +467,7 @@
{
iPreviewPopup->HidePopUp();
}
+
if ( iController )
{
iController->HidePopUp();
@@ -346,9 +479,16 @@
{
if ( iMenuObserver )
{
+ TBool isAlreadySet = iFlags.IsSet( EIdleDisabled );
+
iFlags.Set( EIdleDisabled );
iMenuObserver->ProcessCommandL( KErrCancel );
- iFlags.Clear( EIdleDisabled );
+
+ if( !isAlreadySet )
+ {
+ iFlags.Clear( EIdleDisabled );
+ }
+
}
StartControllerIdleL();
@@ -379,6 +519,20 @@
}
}
+
+// ---------------------------------------------------------------------------
+// CAknStylusPopUpMenu::HideMenu
+// ---------------------------------------------------------------------------
+//
+void CAknStylusPopUpMenu::HideMenu()
+ {
+ if ( iController )
+ {
+ iController->HidePopUp();
+ }
+ }
+
+
// -----------------------------------------------------------------------------
// CAknStylusPopUpMenu::StartControllerIdleL
// -----------------------------------------------------------------------------
@@ -424,3 +578,12 @@
iController = NULL;
}
}
+
+// -----------------------------------------------------------------------------
+// CAknStylusPopUpMenu::CleanLocalRef
+// -----------------------------------------------------------------------------
+//
+void CAknStylusPopUpMenu::CleanLocalRef( TAny* aParam )
+ {
+ static_cast<CAknStylusPopUpMenu*>( aParam )->iIsDeleted = NULL;
+ }