diff -r 5456b4e8b3a8 -r 3321d3e205b6 taskswitcher/taskswitcherui/taskswitcherapp/src/tsfastswapareautils.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/taskswitcher/taskswitcherui/taskswitcherapp/src/tsfastswapareautils.cpp Tue Sep 14 20:58:58 2010 +0300 @@ -0,0 +1,572 @@ +/* +* Copyright (c) 2008 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" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Taskswitcher Fast Swap area UI + * +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "tsfastswapareautils.h" +#include "tsfastswaparea.h" +#include "tsappui.h" +#include "tsfswentry.h" + + +const TInt KLayoutItemCount = 4; + + /* ================================================================================ + * CTsFastSwapTimer + * ================================================================================ + */ + +// ----------------------------------------------------------------------------- +// CTsFastSwapTimer::CTsFastSwapTimer +// ----------------------------------------------------------------------------- +// +CTsFastSwapTimer::CTsFastSwapTimer( MTsFastSwapTimerObserver& aObserver ) +: CTimer( EPriorityStandard ), + iObserver( &aObserver ) + { + } + + +// ----------------------------------------------------------------------------- +// CTsFastSwapTimer::CTsGridHighlightTimer +// ----------------------------------------------------------------------------- +// +CTsFastSwapTimer::~CTsFastSwapTimer() + { + Cancel(); + } + + +// ----------------------------------------------------------------------------- +// CTsFastSwapTimer::ConstructL +// ----------------------------------------------------------------------------- +// +void CTsFastSwapTimer::ConstructL() + { + CTimer::ConstructL(); + CActiveScheduler::Add( this ); + } + + +// ----------------------------------------------------------------------------- +// CTsFastSwapTimer::CTsGridHighlightTimer +// ----------------------------------------------------------------------------- +// +void CTsFastSwapTimer::RunL() + { + iObserver->TimerCompletedL(this); + } + + + +/* ================================================================================ + * CTsBitmapScaleTask + * ================================================================================ + */ + +// ----------------------------------------------------------------------------- +// CTsBitmapScaleTask:: +// ----------------------------------------------------------------------------- +// +CTsBitmapScaleTask::CTsBitmapScaleTask( CTsFastSwapAreaExtension& aObserver ) +: CActive(EPriorityStandard), + iObserver( aObserver ) + { + CActiveScheduler::Add( this ); + } + + +// ----------------------------------------------------------------------------- +// CTsBitmapScaleTask:: +// ----------------------------------------------------------------------------- +// +CTsBitmapScaleTask::~CTsBitmapScaleTask() + { + Cancel(); + delete iScaler; + delete iSourceBmp; + } + + +// ----------------------------------------------------------------------------- +// CTsBitmapScaleTask:: +// ----------------------------------------------------------------------------- +// +void CTsBitmapScaleTask::StartLD( CFbsBitmap* aSourceBitmap, + CFbsBitmap* aTargetBitmap ) + { + if ( !iScaler ) + { + iSourceBmp = aSourceBitmap; + iScaler = CBitmapScaler::NewL(); + iScaler->Scale( &iStatus, *aSourceBitmap, *aTargetBitmap ); + SetActive(); + } + } + + +// ----------------------------------------------------------------------------- +// CTsBitmapScaleTask:: +// ----------------------------------------------------------------------------- +// +void CTsBitmapScaleTask::RunL() + { + iObserver.ScaleFinished( this ); + delete this; + } + + +// ----------------------------------------------------------------------------- +// CTsBitmapScaleTask:: +// ----------------------------------------------------------------------------- +// +void CTsBitmapScaleTask::DoCancel() + { + iScaler->Cancel(); + } + + +/* ================================================================================ + * CTsFastSwapAreaExtension + * ================================================================================ + */ + +// ----------------------------------------------------------------------------- +// CTsFastSwapAreaExtension::NewL +// ----------------------------------------------------------------------------- +// +CTsFastSwapAreaExtension* CTsFastSwapAreaExtension::NewL( CTsFastSwapArea& aFastSwapArea, + CEikonEnv& aEnv ) + { + CTsFastSwapAreaExtension* self = CTsFastSwapAreaExtension::NewLC( + aFastSwapArea, aEnv ); + CleanupStack::Pop( self ); + return self; + } + + +// ----------------------------------------------------------------------------- +// CTsFastSwapAreaExtension::NewLC +// ----------------------------------------------------------------------------- +// +CTsFastSwapAreaExtension* CTsFastSwapAreaExtension::NewLC( CTsFastSwapArea& aFastSwapArea, + CEikonEnv& aEnv ) + { + CTsFastSwapAreaExtension* self = new (ELeave) CTsFastSwapAreaExtension( + aFastSwapArea, aEnv ); + CleanupStack::PushL( self ); + self->ConstructL(); + return self; + } + + +// ----------------------------------------------------------------------------- +// CTsFastSwapAreaExtension::~CTsFastSwapAreaExtension +// ----------------------------------------------------------------------------- +// +CTsFastSwapAreaExtension::~CTsFastSwapAreaExtension() + { + iScaleTasks.ResetAndDestroy(); + } + + +// ----------------------------------------------------------------------------- +// CTsFastSwapAreaExtension::ConstructL +// ----------------------------------------------------------------------------- +// +void CTsFastSwapAreaExtension::ConstructL() + { + } + + +// ----------------------------------------------------------------------------- +// CTsFastSwapAreaExtension::CTsFastSwapAreaExtension +// ----------------------------------------------------------------------------- +// +CTsFastSwapAreaExtension::CTsFastSwapAreaExtension( CTsFastSwapArea& aFastSwapArea, + CEikonEnv& aEnv ) +: iFastSwapArea( aFastSwapArea ), + iEnv( aEnv ) + { + } + +// ----------------------------------------------------------------------------- +// CTsFastSwapAreaExtension::GetCurrentScreenOrientation +// ----------------------------------------------------------------------------- +// +TInt CTsFastSwapAreaExtension::GetCurrentScreenOrientation() + { + TPixelsAndRotation availableRect; + iEnv.ScreenDevice()->GetDefaultScreenSizeAndRotation(availableRect); + return availableRect.iPixelSize.iWidth > availableRect.iPixelSize.iHeight; + } + + +// ----------------------------------------------------------------------------- +// CTsFastSwapAreaExtension::GetVariety +// ----------------------------------------------------------------------------- +// +TBool CTsFastSwapAreaExtension::GetVariety( TInt& aVariety ) + { + aVariety = Layout_Meta_Data::IsLandscapeOrientation() ? 1 : 0; + TBool foreground = static_cast(iEnv.AppUi())->IsForeground(); + if ( foreground ) + { + TInt screenOrientation = GetCurrentScreenOrientation(); + if ( aVariety != screenOrientation ) + { + aVariety = screenOrientation; + return ETrue; + } + } + return EFalse; + } + + +// -------------------------------------------------------------------------- +// CTsFastSwapAreaExtension::GetFastSwapAreaRects +// -------------------------------------------------------------------------- +// +void CTsFastSwapAreaExtension::GetFastSwapAreaRects( RArray& aRects ) + { + TAknLayoutRect gridAppPane; + TAknLayoutRect gridItem; + TAknLayoutRect gridImage; + TInt variety; + TBool disable = GetVariety(variety); + if ( disable ) + { + TRAP_IGNORE(static_cast(iEnv.AppUi())->RequestPopUpL()); + } + variety = Layout_Meta_Data::IsLandscapeOrientation() ? 1 : 0; // double check to avoid layout panic + gridAppPane.LayoutRect( iFastSwapArea.Rect(), + AknLayoutScalable_Apps::tport_appsw_pane_g1( variety ) ); + aRects.Append(gridAppPane); + + gridItem.LayoutRect( gridAppPane.Rect(), + AknLayoutScalable_Apps::cell_tport_appsw_pane( variety, 0, 0 ) ); + aRects.Append(gridItem); + + gridImage.LayoutRect( gridItem.Rect(), + AknLayoutScalable_Apps::cell_tport_appsw_pane_g1( variety ) ); + aRects.Append(gridImage); + + if ( disable ) + { + TRAP_IGNORE(static_cast(iEnv.AppUi())->DisablePopUpL()); + } + } + + +// ----------------------------------------------------------------------------- +// CTsFastSwapAreaExtension::ItemPosition +// ----------------------------------------------------------------------------- +// +TPoint CTsFastSwapAreaExtension::ItemViewPosition( TInt aItemIdx ) + { + TPoint retVal = iFastSwapArea.Rect().iTl; + TInt maxItemsOnScreen = iFastSwapArea.GetGridItemData( CTsFastSwapArea::EMaxItemsOnScreen ); + TInt gridItemWidth = iFastSwapArea.GetGridItemData( CTsFastSwapArea::EGridItemWidth ); + TInt gridItemGap = iFastSwapArea.GetGridItemData( CTsFastSwapArea::EGridItemGap ); + + if ( aItemIdx < 0 ) + { + // No items + retVal.iX = 0; + } + else if ( aItemIdx == 0 ) + { + // First item + if( AknLayoutUtils::LayoutMirrored() ) + { + if ( iFastSwapArea.GridItemCount() > maxItemsOnScreen ) + { + retVal.iX = iFastSwapArea.GridWorldSize().iWidth - iFastSwapArea.Rect().Width(); + } + else + { + retVal.iX = 0; + } + } + else // normal layout + { + retVal.iX = 0; + } + } + else if ( aItemIdx == iFastSwapArea.GridItemCount() - 1 ) + { + // Last item selected + if( AknLayoutUtils::LayoutMirrored() ) + { + retVal.iX = 0; + } + else // normal layout + { + if ( iFastSwapArea.GridItemCount() > maxItemsOnScreen ) + { + retVal.iX = iFastSwapArea.GridWorldSize().iWidth - iFastSwapArea.Rect().Width(); + } + else + { + retVal.iX = 0; + } + } + } + else + { + // Middle item + TInt screenMiddleItemOffset = ( iFastSwapArea.Rect().Width() - gridItemWidth ) / 2; + if( AknLayoutUtils::LayoutMirrored() ) + { + retVal.iX = gridItemWidth * ( iFastSwapArea.GridItemCount() - 1 - aItemIdx ) - screenMiddleItemOffset; + retVal.iX += ( iFastSwapArea.GridItemCount() - 1 - aItemIdx ) * gridItemGap; + } + else // normal layout + { + retVal.iX = gridItemWidth * aItemIdx - screenMiddleItemOffset; + retVal.iX += gridItemGap * aItemIdx; + } + if ( retVal.iX < 0 ) + { + retVal.iX = 0; + } + // aligin to grid end edge in case + // (item's position + draw area) extends over grid area and + // (all items cover more than grid area or penultimate item) + else if ( retVal.iX + iFastSwapArea.Rect().Width() > iFastSwapArea.GridWorldSize().iWidth && + (iFastSwapArea.GridWorldSize().iWidth > gridItemWidth * iFastSwapArea.GridItemCount() || + (aItemIdx > 1 && aItemIdx == iFastSwapArea.GridItemCount() - 2 )) ) + { + retVal.iX = iFastSwapArea.GridWorldSize().iWidth - iFastSwapArea.Rect().Width(); + } + } + + // Return middle of the view rectangle + retVal.iX += iFastSwapArea.Rect().Width() / 2; + + return retVal; + } + + +// ----------------------------------------------------------------------------- +// CTsFastSwapAreaExtension::ViewToVisibleItem +// ----------------------------------------------------------------------------- +// +TInt CTsFastSwapAreaExtension::ViewToVisibleItem( const TPoint aViewPos ) + { + TInt retVal(0); + TPoint absViewPos = aViewPos; + absViewPos.iX -= iFastSwapArea.Rect().Width() / 2; + if ( absViewPos.iX < 0 ) + { + if ( AknLayoutUtils::LayoutMirrored() ) + { + // View crossed left border of grid world rect, last item selected + retVal = iFastSwapArea.GridItemCount() - 1; + } + else // normal layout + { + // View crossed left border of grid world rect, first item selected + retVal = 0; + } + } + else if ( absViewPos.iX + iFastSwapArea.Rect().Width() > iFastSwapArea.GridWorldSize().iWidth ) + { + if ( AknLayoutUtils::LayoutMirrored() ) + { + // View crossed right border of grid world rect, first item selected + retVal = 0; + } + else // normal layout + { + // View crossed right border of grid world rect, last item selected + retVal = iFastSwapArea.GridItemCount() - 1; + } + } + else + { + TInt retItemPosX(0); + TInt offsetCheck = iFastSwapArea.GridWorldSize().iWidth; + // View inside of grid world rect + for ( TInt i = 0 ; i < iFastSwapArea.GridItemCount(); i++ ) + { + TInt itemPosX = ItemViewPosition( i ).iX; + TInt offset = aViewPos.iX - itemPosX; + if ( Abs( offset ) <= offsetCheck ) + { + offsetCheck = Abs( offset ); + retVal = i; + retItemPosX = itemPosX; + } + else + { + break; + } + } + // Check if item is fully visible. If not + // return next one if possible + TInt gridItemWidth = iFastSwapArea.GetGridItemData( CTsFastSwapArea::EGridItemWidth ); + if ( retItemPosX - gridItemWidth / 2 < absViewPos.iX && + retVal + 1 < iFastSwapArea.GridItemCount() ) + { + retVal++; + } + } + + return retVal; + } + + +// ----------------------------------------------------------------------------- +// CTsFastSwapAreaExtension::LaunchPopupFeedback +// ----------------------------------------------------------------------------- +// +void CTsFastSwapAreaExtension::LaunchPopupFeedback() + { + if ( AknLayoutUtils::PenEnabled() ) + { + MTouchFeedback* feedback = MTouchFeedback::Instance(); + if ( feedback ) + { + TTouchLogicalFeedback fbLogicalType = ETouchFeedbackPopUp; + if ( CAknTransitionUtils::TransitionsEnabled( + AknTransEffect::EComponentTransitionsOff ) ) + { + fbLogicalType = ETouchFeedbackIncreasingPopUp; + } + feedback->InstantFeedback( &iFastSwapArea, + fbLogicalType, + ETouchFeedbackVibra, + TPointerEvent() ); + } + } + } + + +// ----------------------------------------------------------------------------- +// CTsFastSwapAreaExtension::PreferredImageSize +// ----------------------------------------------------------------------------- +// +TSize CTsFastSwapAreaExtension::PreferredImageSize() + { + TAknLayoutRect gridImage; + TRAP_IGNORE( + RArray rects; + CleanupClosePushL(rects); + rects.ReserveL(KLayoutItemCount); + GetFastSwapAreaRects(rects); + gridImage = rects[2]; + CleanupStack::PopAndDestroy(&rects); + ); + return gridImage.Rect().Size(); + } + +// -------------------------------------------------------------------------- +// CTsFastSwapAreaExtension::CalculateSizePreserveRatio +// -------------------------------------------------------------------------- +// +TSize CTsFastSwapAreaExtension::CalculateSizePreserveRatio( + const TSize& aTargetAreaSize, + const TSize& aSourceSize ) + { + const TReal + resizedAspectRatio(aTargetAreaSize.iWidth/(TReal)aTargetAreaSize.iHeight); + const TReal + orginalAspectRatio(aSourceSize.iWidth/(TReal)aSourceSize.iHeight); + //this condition avoid empty margins ( bigger output ). to realy fit area change it + const TReal scaleFactor = + ( orginalAspectRatio > resizedAspectRatio ) ? + (aTargetAreaSize.iHeight /(TReal)aSourceSize.iHeight) ://scale by height + (aTargetAreaSize.iWidth /(TReal)aSourceSize.iWidth) ;//scale by width + return TSize(aSourceSize.iWidth * scaleFactor, aSourceSize.iHeight * scaleFactor); + } + + +// -------------------------------------------------------------------------- +// CTsFastSwapAreaExtension::CopyBitmapL +// Copy and scale. +// -------------------------------------------------------------------------- +// +CFbsBitmap* CTsFastSwapAreaExtension::CopyBitmapL( TInt aFbsHandle, TSize aSize, TBool aIsScreenshot ) + { + CFbsBitmap* ret = new (ELeave) CFbsBitmap(); + CleanupStack::PushL( ret ); + + CFbsBitmap* bmp = new (ELeave) CFbsBitmap(); + CleanupStack::PushL( bmp ); + User::LeaveIfError( bmp->Duplicate( aFbsHandle ) ); + + // First scale using normal method, to show "draft" screenshots. + // Do not always use aSize, preserving the aspect ratio is quite + // important when showing app icons instead of screenshots + TSize sz = CalculateSizePreserveRatio( aSize, bmp->SizeInPixels() ); + User::LeaveIfError( ret->Create( sz, bmp->DisplayMode() ) ); + AknIconUtils::ScaleBitmapL( sz, ret, bmp ); + + // Second, if it is screenshot, perform quality improvement scaling + if ( aIsScreenshot ) + { + CTsBitmapScaleTask* rotaTask = new (ELeave) CTsBitmapScaleTask( *this ); + CleanupStack::PushL( rotaTask ); + iScaleTasks.AppendL( rotaTask ); + rotaTask->StartLD( bmp, ret ); // ownership of bmp transferred + CleanupStack::Pop( rotaTask ); + CleanupStack::Pop( bmp ); + } + else + { + CleanupStack::PopAndDestroy( bmp ); + } + + CleanupStack::Pop( ret ); + return ret; + } + + +// -------------------------------------------------------------------------- +// CTsFastSwapAreaExtension::CancelScaleTasks +// -------------------------------------------------------------------------- +// +void CTsFastSwapAreaExtension::CancelScaleTasks() + { + iScaleTasks.ResetAndDestroy(); + } + + +// -------------------------------------------------------------------------- +// CTsFastSwapAreaExtension::ScaleFinished +// -------------------------------------------------------------------------- +// +void CTsFastSwapAreaExtension::ScaleFinished( CTsBitmapScaleTask* iFinishedTask ) + { + TInt task = iScaleTasks.Find( iFinishedTask ); + if ( task != KErrNotFound ) + { + iScaleTasks.Remove( task ); + } + iFastSwapArea.DrawDeferred(); + } + + // End of file