diff -r 2f259fa3e83a -r 8ca85d2f0db7 uifw/EikStd/coctlsrc/aknstyluspopupmenu.cpp --- a/uifw/EikStd/coctlsrc/aknstyluspopupmenu.cpp Tue Feb 02 01:00:49 2010 +0200 +++ b/uifw/EikStd/coctlsrc/aknstyluspopupmenu.cpp Fri Feb 19 23:04:46 2010 +0200 @@ -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" @@ -119,6 +119,7 @@ // CAknStylusPopUpMenu::~CAknStylusPopUpMenu() { + iContent->SetObserver(NULL); if ( iIsDeleted ) { *iIsDeleted = ETrue; @@ -223,7 +224,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 +234,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 ); }