--- /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 <w32std.h>
+#include <eikenv.h>
+#include <layoutmetadata.cdl.h>
+#include <touchfeedback.h>
+#include <akntransitionutils.h>
+#include <akntranseffect.h>
+#include <aknlayoutscalable_apps.cdl.h>
+#include <bitmaptransforms.h>
+
+
+#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<CTsAppUi*>(iEnv.AppUi())->IsForeground();
+ if ( foreground )
+ {
+ TInt screenOrientation = GetCurrentScreenOrientation();
+ if ( aVariety != screenOrientation )
+ {
+ aVariety = screenOrientation;
+ return ETrue;
+ }
+ }
+ return EFalse;
+ }
+
+
+// --------------------------------------------------------------------------
+// CTsFastSwapAreaExtension::GetFastSwapAreaRects
+// --------------------------------------------------------------------------
+//
+void CTsFastSwapAreaExtension::GetFastSwapAreaRects( RArray<TAknLayoutRect>& aRects )
+ {
+ TAknLayoutRect gridAppPane;
+ TAknLayoutRect gridItem;
+ TAknLayoutRect gridImage;
+ TInt variety;
+ TBool disable = GetVariety(variety);
+ if ( disable )
+ {
+ TRAP_IGNORE(static_cast<CTsAppUi*>(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<CTsAppUi*>(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<TAknLayoutRect> 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