--- a/uifw/AvKon/src/akndiscreetpopupcontrol.cpp Tue Feb 02 01:00:49 2010 +0200
+++ b/uifw/AvKon/src/akndiscreetpopupcontrol.cpp Fri Apr 16 15:13:44 2010 +0300
@@ -26,19 +26,26 @@
#include <bautils.h>
#include <barsread.h>
#include <gulicon.h>
-#include <gfxtranseffect/gfxtranseffect.h>
-#include <akntransitionutils.h>
#include <avkon.hrh>
#include "akndiscreetpopupcontrol.h"
#include "akndiscreetpopupdrawer.h"
_LIT( KDiscreetPopupWindowGroupName, "Discreet pop-up" );
+const TInt KOpacityChangeSpeed( 18 );
+const TInt KAlphaMax( 255 );
+const TInt KAlphaMin( 0 );
const TInt KShortTimeout( 1500000 );
const TInt KLongTimeout( 3000000 );
+const TInt KShowDelay( 300000 );
+const TInt KShowInterval( 50000 );
+const TInt KHideDelay( 50000 );
+const TInt KHideInterval( 50000 );
const TInt KGlobalShowOrdinalPriority( ECoeWinPriorityAlwaysAtFront * 4 );
const TInt KLocalShowOrdinalPriority( ECoeWinPriorityNormal + 1 );
const TInt KLocalHideOrdinalPosition( -10 );
+const TInt KOpacityDismissFactor( 3 );
+const TInt KMaxFadeTime( 1000000 );
/**
* Internal discreet popup control flags.
@@ -48,6 +55,7 @@
EPressedDown, // Pointer down is received in popup area
EDismissed, // Popup is dismissed (pointer up is received in popup area)
EGlobal, // Popup is global
+ EFading, // Popup is closing (fading)
EDragged // Pointer is dragged while popup open
};
@@ -180,9 +188,6 @@
{
HidePopup();
}
-
- GfxTransEffect::Deregister( this );
-
if ( iInternalFlags.IsSet( EGlobal ) )
{
iWindowGroup.Close();
@@ -250,6 +255,11 @@
//
void CAknDiscreetPopupControl::MakeVisible( TBool aVisible )
{
+ if ( iTimer )
+ {
+ iTimer->Cancel();
+ }
+
CCoeControl::MakeVisible( aVisible );
if( iInternalFlags.IsSet( EGlobal ) )
@@ -260,7 +270,21 @@
{
Window().SetOrdinalPosition( 0, KLocalShowOrdinalPriority );
}
-
+
+ if ( aVisible && iTimer )
+ {
+ iAlpha = 0;
+ iInternalFlags.Clear( EFading );
+ iInternalFlags.Clear( EDismissed );
+
+ iTimer->Start( KShowDelay,
+ KShowInterval,
+ TCallBack( TimeOut, this ) );
+
+ iFadeTime.HomeTime();
+ TTimeIntervalMicroSeconds32 timeout( KShowDelay );
+ iFadeTime += timeout;
+ }
UpdateNonFadingStatus();
}
@@ -289,13 +313,14 @@
{
iInternalFlags.Set( EGlobal );
}
+ iInternalFlags.Set( EDismissed );
- iInternalFlags.Set( EDismissed );
- iCommand = aCommand;
- iCommandObserver = aCommandObserver;
-
- GfxTransEffect::Register( this, KGfxDiscreetPopupControlUid );
-
+ // Action allowed only when touch enabled
+ if ( AknLayoutUtils::PenEnabled() )
+ {
+ iCommand = aCommand;
+ iCommandObserver = aCommandObserver;
+ }
AKNTASHOOK_ADD( this, "CAknDiscreetPopupControl" );
}
@@ -334,7 +359,15 @@
iTimer = CPeriodic::NewL( 0 );
- EnableWindowTransparency();
+ // try to enable window transparency
+ if( CAknEnv::Static()->TransparencyEnabled() )
+ {
+ Window().SetRequiredDisplayMode( EColor16MA );
+ if ( Window().SetTransparencyAlphaChannel() == KErrNone )
+ {
+ Window().SetBackgroundColor( ~0 );
+ }
+ }
Window().SetPointerGrab( ETrue );
EnableDragEvents();
@@ -401,13 +434,74 @@
//
void CAknDiscreetPopupControl::DoTimeOut()
{
- if ( !iInternalFlags.IsSet( EPressedDown ) )
+ if ( iInternalFlags.IsSet( EFading ) && iAlpha <= KAlphaMin )
{
+ // popup has faded completely, exit
TRAP_IGNORE( RequestExitL() );
}
else
{
- iTimer->Cancel();
+ TInt opacityChange =
+ iInternalFlags.IsSet( EFading ) ? -KOpacityChangeSpeed : KOpacityChangeSpeed;
+
+ if ( iInternalFlags.IsSet( EPressedDown )
+ && iInternalFlags.IsSet( EFading ) )
+ {
+ iAlpha = KAlphaMax;
+ opacityChange = 0;
+ }
+
+ if ( iInternalFlags.IsSet( EDismissed ) )
+ {
+ opacityChange *= KOpacityDismissFactor;
+ }
+ iAlpha += opacityChange;
+
+ TTime now;
+ now.HomeTime();
+ TInt fadeTime( now.MicroSecondsFrom( iFadeTime ).Int64() );
+
+ if ( fadeTime > KMaxFadeTime )
+ {
+ if ( !iInternalFlags.IsSet( EFading ) )
+ {
+ // fade in animation is taking too long,
+ // make popup fully visible
+ iAlpha = KAlphaMax;
+ }
+ else
+ {
+ // fade out animation is taking too long,
+ // make popup invisible
+ iAlpha = KAlphaMin;
+ }
+ }
+
+ if ( iAlpha >= KAlphaMax )
+ {
+ // popup is completely visible. set the EFading flag and set timeout
+ iAlpha = KAlphaMax;
+ iInternalFlags.Set( EFading );
+ iTimer->Cancel();
+ //fade out after timeout
+ TTimeIntervalMicroSeconds32 timeout( KShortTimeout );
+ if ( iFlags & KAknDiscreetPopupDurationLong )
+ {
+ timeout = KLongTimeout;
+ }
+ iTimer->Start( timeout,
+ KHideInterval,
+ TCallBack( TimeOut, this ) );
+
+ iFadeTime.HomeTime();
+ iFadeTime += timeout;
+ }
+ else if ( iAlpha < KAlphaMin )
+ {
+ iAlpha = KAlphaMin;
+ }
+
+ DrawNow();
}
}
@@ -539,30 +633,7 @@
User::ResetInactivityTime();
PlayTone();
-
- if ( GfxTransEffect::IsRegistered( this ) )
- {
- iInternalFlags.Clear( EDismissed );
- GfxTransEffect::Begin( this, KGfxControlAppearAction );
- MakeVisible( ETrue );
- GfxTransEffect::SetDemarcation( this, iPosition );
- GfxTransEffect::End( this );
- }
- else
- {
- MakeVisible( ETrue );
- }
-
- TTimeIntervalMicroSeconds32 timeout( KShortTimeout );
-
- if ( iFlags & KAknDiscreetPopupDurationLong )
- {
- timeout = KLongTimeout;
- }
-
- iTimer->Start( timeout,
- 0,
- TCallBack( TimeOut, this ) );
+ MakeVisible( ETrue );
}
@@ -572,17 +643,7 @@
//
void CAknDiscreetPopupControl::HidePopup()
{
- if ( GfxTransEffect::IsRegistered( this ) )
- {
- GfxTransEffect::Begin( this, KGfxControlDisappearAction );
- MakeVisible( EFalse );
- GfxTransEffect::End( this );
- }
- else
- {
- MakeVisible( EFalse );
- }
-
+ MakeVisible( EFalse );
AppUi()->RemoveFromStack( this );
}
@@ -639,7 +700,26 @@
return;
}
- iDrawer->Draw( SystemGc(), Rect() );
+ CFbsBitmap* popupBitmap( iDrawer->PopupBitmap( Size() ) );
+
+ // create a transparent mask for the popup
+ CFbsBitmap* transParentBitmap =
+ iDrawer->TransparentMask( popupBitmap->SizeInPixels(), iAlpha );
+
+ // blit the bitmap to screen with the transparent mask
+ CWindowGc& gc = SystemGc();
+ if( transParentBitmap )
+ {
+ gc.BitBltMasked( Rect().iTl,
+ popupBitmap,
+ popupBitmap->SizeInPixels(),
+ transParentBitmap,
+ EFalse );
+ }
+ else
+ {
+ gc.BitBlt( Rect().iTl, popupBitmap );
+ }
}
@@ -741,7 +821,11 @@
&& iInternalFlags.IsClear( EDismissed ) )
{
SetPressedDownState( ETrue );
- ImmediateFeedback( ETouchFeedbackSensitive );
+ // Play feedback only when popup is completely visible (or fading away)
+ if ( iInternalFlags.IsSet( EFading ) )
+ {
+ ImmediateFeedback( ETouchFeedbackSensitive );
+ }
}
// Pointer drag - reset pressed-down state if pointer out of popup area
@@ -761,18 +845,21 @@
// Pointer up - reset pressed-down state
else if ( aPointerEvent.iType == TPointerEvent::EButton1Up )
{
- if ( eventInRect )
+ if ( iInternalFlags.IsSet( EFading )
+ && iInternalFlags.IsSet( EPressedDown )
+ && eventInRect )
{
+ // Notify popup tap
NotifyObserverL();
+ // Start fading away
+ if ( iInternalFlags.IsClear( EDismissed ) )
+ {
+ iTimer->Cancel();
+ iInternalFlags.Set( EFading );
+ iInternalFlags.Set( EDismissed );
+ iTimer->Start( KHideDelay, KHideInterval, TCallBack( TimeOut, this ) );
+ }
}
-
- // Start fading away
- if ( iInternalFlags.IsClear( EDismissed ) )
- {
- iInternalFlags.Set( EDismissed );
- RequestExitL();
- }
-
SetPressedDownState( EFalse );
}
}