diff -r 000000000000 -r ff3acec5bc43 mpxmusicplayer/mediakeyhandler/src/mpxnotifierdialog.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mpxmusicplayer/mediakeyhandler/src/mpxnotifierdialog.cpp Thu Dec 17 08:45:05 2009 +0200 @@ -0,0 +1,710 @@ +/* +* Copyright (c) 2006 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: Implementation of media key handler +* +*/ + + + +// INCLUDE FILES +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mpxlog.h" +#include "mpxnotifierdialog.h" + +using namespace AknLayoutScalable_Apps; + + +// CONSTANTS +const TInt KMPXComponentsCount = CMPXNotifierDialog::EMPXComponentsCount; + +const TInt KMPXOneSecInMicroSecs( 1000000 ); +const TInt KMPXOneHourInSeconds( 3600 ); +const TInt KMPXOneHundredHoursInSecs( 360000 ); +const TInt KMPXDurationDisplayResvLen( 10 ); + +const TInt KMPXWindowPosition = 10; // window group's priority +const TInt KMPXInactivityTime = 4000000; // 4 seconds - close window after this +_LIT( KMPXInfoPopupWgName, "MPXInfoPopup" ); // window groups name + +_LIT( KMPXMediaKeyHandlerMbmFile, "mpxmediakeyhandler.mbm" ); + + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// C++ default constructor can NOT contain any code, that +// might leave. +// --------------------------------------------------------------------------- +// +CMPXNotifierDialog::CMPXNotifierDialog() + { + } + +// --------------------------------------------------------------------------- +// Symbian 2nd phase constructor can leave. +// --------------------------------------------------------------------------- +// +void CMPXNotifierDialog::ConstructL() + { + // create a window group for popup + // needed to prevent apps noticing this window + RWsSession& wsSession = iCoeEnv->WsSession(); + iWindowGroup = RWindowGroup( wsSession ); + User::LeaveIfError( iWindowGroup.Construct( ( TUint32 )&iWindowGroup, EFalse ) ); + iWindowGroup.AutoForeground( EFalse ); + iEikonEnv->EikAppUi()->AddToStackL( this ); + + CApaWindowGroupName* name = CApaWindowGroupName::NewLC( + wsSession, ( TUint32 )&iWindowGroup ); + name->SetHidden( ETrue ); + name->SetCaptionL( KMPXInfoPopupWgName ); // Available to OOM watcher so this won't be closed + User::LeaveIfError( name->SetWindowGroupName( iWindowGroup ) ); + CleanupStack::PopAndDestroy( name ); + + iWindowGroup.SetOrdinalPosition( 0, ECoeWinPriorityNeverAtFront ); + + // create control's window to own window group + CreateWindowL( &iWindowGroup ); + + // create icon & label controls + iSongLabel = new ( ELeave ) CEikLabel(); + iSongLabel->SetContainerWindowL( *this ); + iSongLabel->SetTextL( KNullDesC ); + + iTimeLabel = new ( ELeave ) CEikLabel(); + iTimeLabel->SetContainerWindowL( *this ); + iTimeLabel->SetTextL( KNullDesC ); + + CreateIconsL(); + + // Timer + iTimer = CPeriodic::NewL( CActive::EPriorityStandard ); + + // for watching when we go active idle + iPSKeyWatcher = CMPXPSKeyWatcher::NewL( KPSUidAiInformation, KActiveIdleState, this ); + + MakeVisible( EFalse ); + ResizeInfoPopup(); + ActivateL(); + } + +// --------------------------------------------------------------------------- +// Two-phased constructor. +// --------------------------------------------------------------------------- +// +CMPXNotifierDialog* CMPXNotifierDialog::NewL() + { + CMPXNotifierDialog* self = new( ELeave ) CMPXNotifierDialog(); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +// --------------------------------------------------------------------------- +// Destructor +// --------------------------------------------------------------------------- +// +CMPXNotifierDialog::~CMPXNotifierDialog() + { + iEikonEnv->EikAppUi()->RemoveFromStack( this ); + delete iPSKeyWatcher; + iWindowGroup.Close(); + if (iTimer) + iTimer->Cancel(); + delete iTimer; + delete iSongLabel; + delete iTimeLabel; + delete iPlayIcon; + delete iPauseIcon; + delete iFFIcon; + delete iFRIcon; + } + +// --------------------------------------------------------------------------- +// Shows pop-up dialog. +// --------------------------------------------------------------------------- +// +void CMPXNotifierDialog::ShowInfoPopupL( + TMPXPlaybackPopupIcons aIcon, + const TDesC& aTitle, + TInt aTime, + TMPXPlaybackPopupModes aMode ) + { + MPX_DEBUG2( "CMPXNotifierDialog::ShowInfoPopupL aMode = %d", aMode ); + if ( ( EMPXPopupShowIfVisible == aMode && !IsVisible() ) || + ( EMPXPopupShowIfVisibleRestartTimer == aMode && !IsVisible() ) ) + { + MPX_DEBUG1( "CMPXNotifierDialog::ShowInfoPopupL do nothing" ); + return; + } + + UpdateInfoPopupL( aIcon, aTitle, aTime ); + + if ( EMPXPopupTimeout == aMode || + EMPXPopupShowIfVisibleRestartTimer == aMode ) + { + MPX_DEBUG1( "CMPXNotifierDialog::ShowInfoPopupL starting timer" ); + iTimer->Cancel(); + iTimer->Start( + KMPXInactivityTime, + KMPXInactivityTime, + TCallBack( TimerCallback, this ) ); + } + else if ( EMPXPopupNoTimeout == aMode ) + { + MPX_DEBUG1( "CMPXNotifierDialog::ShowInfoPopupL canceling timer" ); + iTimer->Cancel(); + } + } + +// --------------------------------------------------------------------------- +// Removes pop-up from screen. +// --------------------------------------------------------------------------- +// +void CMPXNotifierDialog::CancelInfoPopup() + { + MPX_DEBUG1( "CMPXNotifierDialog::CancelInfoPopup" ); + iTimer->Cancel(); + if ( IsVisible() ) + { + iWindowGroup.SetOrdinalPosition( 0, ECoeWinPriorityNeverAtFront ); + MakeVisible( EFalse ); + } + } + +// --------------------------------------------------------------------------- +// Gets notified when display orientation hange is started +// --------------------------------------------------------------------------- +// +void CMPXNotifierDialog::NotifyOrientationChangeBegin() + { + // ::HandeResourceChange() will unhide the dialog as soon as the + // orientation change has been completed. KEikDynamicLayoutVariantSwitch comes + // too late so the layout is not correct from the beginning + if( IsVisible() ) + { + MakeVisible( EFalse ); + iReopenDialog = ETrue; + } + } + +// Updates pop-up dialog contents. +// --------------------------------------------------------------------------- +// +void CMPXNotifierDialog::UpdateInfoPopupL( + TMPXPlaybackPopupIcons aIcon, + const TDesC& aTitle, + TInt aTime ) + { + ShowIcon( aIcon ); + + // Set label text + // magic: allocate 3 chars more (make sure "..." fits). + HBufC* buf = HBufC::NewLC( aTitle.Length() + 3 ); + *buf = aTitle; + TPtr ptr( buf->Des() ); + AknTextUtils::ClipToFit( + ptr, + *iSongLabel->Font(), + iSongLabel->Rect().Width() ); + iSongLabel->SetTextL( *buf ); + CleanupStack::PopAndDestroy( buf ); + + // Set duration label + if ( aTime != KErrNotFound ) + { + HBufC* duration = DisplayableDurationL( aTime ); + CleanupStack::PushL( duration ); + iTimeLabel->SetTextL( *duration ); + CleanupStack::PopAndDestroy( duration ); + } + else + { + iTimeLabel->SetTextL( KNullDesC ); + } + + if ( !IsVisible() ) + { + // make this window visible + iWindowGroup.SetOrdinalPosition( 0, KMPXWindowPosition ); + MakeVisible( ETrue ); + } + DrawDeferred(); + } + +// --------------------------------------------------------------------------- +// Create icons. +// --------------------------------------------------------------------------- +// +void CMPXNotifierDialog::CreateIconsL() + { + delete iPlayIcon; + iPlayIcon = NULL; + iPlayIcon = new ( ELeave ) CEikImage(); + iPlayIcon->SetContainerWindowL( *this ); + ConstructImageL( + iPlayIcon, + AknsUtils::SkinInstance(), + KAknsIIDQgnIndiMupPlay, + KAknsIIDQsnIconColors, + EAknsCIQsnIconColorsCG26, + EMbmMpxmediakeyhandlerQgn_indi_mup_play, + EMbmMpxmediakeyhandlerQgn_indi_mup_play_mask ); + + delete iPauseIcon; + iPauseIcon = NULL; + iPauseIcon = new ( ELeave ) CEikImage(); + iPauseIcon->SetContainerWindowL( *this ); + ConstructImageL( + iPauseIcon, + AknsUtils::SkinInstance(), + KAknsIIDQgnIndiMupPause, + KAknsIIDQsnIconColors, + EAknsCIQsnIconColorsCG26, + EMbmMpxmediakeyhandlerQgn_indi_mup_pause, + EMbmMpxmediakeyhandlerQgn_indi_mup_pause_mask ); + delete iFFIcon; + iFFIcon = NULL; + iFFIcon = new ( ELeave ) CEikImage(); + iFFIcon->SetContainerWindowL( *this ); + ConstructImageL( + iFFIcon, + AknsUtils::SkinInstance(), + KAknsIIDQgnIndiMupForw, + KAknsIIDQsnIconColors, + EAknsCIQsnIconColorsCG26, + EMbmMpxmediakeyhandlerQgn_indi_mup_forw, + EMbmMpxmediakeyhandlerQgn_indi_mup_forw_mask ); + + delete iFRIcon; + iFRIcon = NULL; + iFRIcon = new ( ELeave ) CEikImage(); + iFRIcon->SetContainerWindowL( *this ); + ConstructImageL( + iFRIcon, + AknsUtils::SkinInstance(), + KAknsIIDQgnIndiMupRew, + KAknsIIDQsnIconColors, + EAknsCIQsnIconColorsCG26, + EMbmMpxmediakeyhandlerQgn_indi_mup_rew, + EMbmMpxmediakeyhandlerQgn_indi_mup_rew_mask ); + } + +// --------------------------------------------------------------------------- +// Constructs skinnable icon. +// --------------------------------------------------------------------------- +// +void CMPXNotifierDialog::ConstructImageL( + CEikImage* aImage, + MAknsSkinInstance* aSkin, + const TAknsItemID& aId, + const TAknsItemID& aColorId, + TInt aColorIndex, + TInt aBitmapId, + TInt aMaskId ) + { + CFbsBitmap* bitmap = NULL; + CFbsBitmap* mask = NULL; + + TParse parse; + parse.Set( KMPXMediaKeyHandlerMbmFile, &KDC_APP_RESOURCE_DIR, NULL ); + TFileName iconFile( parse.FullName() ); + User::LeaveIfError( MPXUser::CompleteWithDllPath( iconFile ) ); + + AknsUtils::CreateColorIconL( + aSkin, + aId, + aColorId, + aColorIndex, + bitmap, + mask, + iconFile, + aBitmapId, + aMaskId, + KRgbBlack ); + + aImage->SetPicture( bitmap, mask ); // Owership transferred to CEikImage + } + +// --------------------------------------------------------------------------- +// Resize info popup. +// --------------------------------------------------------------------------- +// +void CMPXNotifierDialog::ResizeInfoPopup() + { + TRect appRect = iEikonEnv->EikAppUi()->ApplicationRect(); + + // get parent rectangle (status pane) + TAknWindowLineLayout statusPane = AknLayout::status_pane( appRect, 0 ); + TAknLayoutRect res; + res.LayoutRect( appRect, statusPane ); + TRect parentRect = res.Rect(); + + // set the rectangle + TAknWindowComponentLayout l = popup_mup_playback_window(); + res.LayoutRect( parentRect, l.LayoutLine() ); + SetRect( res.Rect() ); + DrawNow(); + } + +// --------------------------------------------------------------------------- +// Sets pop-up layouts. +// --------------------------------------------------------------------------- +// +void CMPXNotifierDialog::SetLayoutsL( TBool aLong ) + { + TAknWindowComponentLayout l; + // play icon + l = popup_mup_playback_window_g1(); + AknLayoutUtils::LayoutImage( iPlayIcon, Rect(), l.LayoutLine() ); + // pause icon + l = popup_mup_playback_window_g1(); + AknLayoutUtils::LayoutImage( iPauseIcon, Rect(), l.LayoutLine() ); + // FF icon + l = popup_mup_playback_window_g1(); + AknLayoutUtils::LayoutImage( iFFIcon, Rect(), l.LayoutLine() ); + // FR icon + l = popup_mup_playback_window_g1(); + AknLayoutUtils::LayoutImage( iFRIcon, Rect(), l.LayoutLine() ); + // song label + TAknTextComponentLayout t = popup_mup_playback_window_t1(); + AknLayoutUtils::LayoutLabel( iSongLabel, Rect(), t.LayoutLine() ); + // time label + if( aLong ) + { + t = popup_mup_playback_window_t2( 1 ); + } + else + { + t = popup_mup_playback_window_t2(); + } + + AknLayoutUtils::LayoutLabel( iTimeLabel, Rect(), t.LayoutLine() ); + + // Set label color + TRgb color; + MAknsSkinInstance* skin = AknsUtils::SkinInstance(); + TInt error = AknsUtils::GetCachedColor( + skin, + color, + KAknsIIDQsnTextColors, + EAknsCIQsnTextColorsCG19 ); + if ( !error ) + { + AknLayoutUtils::OverrideControlColorL( + *iSongLabel, + EColorLabelText, + color ); + + AknLayoutUtils::OverrideControlColorL( + *iTimeLabel, + EColorLabelText, + color ); + } + } + +// --------------------------------------------------------------------------- +// Show playback icon. +// --------------------------------------------------------------------------- +// +void CMPXNotifierDialog::ShowIcon( + TMPXPlaybackPopupIcons aIcon ) + { + + switch ( aIcon ) + { + case EMPXPopupPlayIcon: + { + iIconShown = EMPXPopupPlayIcon; + iPlayIcon->MakeVisible( ETrue ); + iPauseIcon->MakeVisible( EFalse ); + iFFIcon->MakeVisible( EFalse ); + iFRIcon->MakeVisible( EFalse ); + break; + } + case EMPXPopupPauseIcon: + { + iIconShown = EMPXPopupPauseIcon; + iPlayIcon->MakeVisible( EFalse ); + iPauseIcon->MakeVisible( ETrue ); + iFFIcon->MakeVisible( EFalse ); + iFRIcon->MakeVisible( EFalse ); + break; + } + case EMPXPopupFFIcon: + { + iIconShown = EMPXPopupFFIcon; + iFFIcon->MakeVisible( ETrue ); + iPlayIcon->MakeVisible( EFalse ); + iPauseIcon->MakeVisible( EFalse ); + iFRIcon->MakeVisible( EFalse ); + break; + } + case EMPXPopupFRIcon: + { + iIconShown = EMPXPopupFFIcon; + iPlayIcon->MakeVisible( EFalse ); + iPauseIcon->MakeVisible( EFalse ); + iFFIcon->MakeVisible( EFalse ); + iFRIcon->MakeVisible( ETrue ); + break; + } + default: + { + iIconShown = EMPXPopupNoneIcon; + iPlayIcon->MakeVisible( EFalse ); + iPauseIcon->MakeVisible( EFalse ); + iFFIcon->MakeVisible( EFalse ); + iFRIcon->MakeVisible( EFalse ); + break; + } + } + } + +// --------------------------------------------------------------------------- +// Callback for timer +// --------------------------------------------------------------------------- +// +TInt CMPXNotifierDialog::TimerCallback( TAny* aPtr ) + { + MPX_DEBUG1( "CMPXNotifierDialog::TimerCallback" ); + static_cast( aPtr )->CancelInfoPopup(); + return KErrNone; + } + +// --------------------------------------------------------------------------- +// Convert to displayable duration. +// --------------------------------------------------------------------------- +// +HBufC* CMPXNotifierDialog::DisplayableDurationL( + TInt aDuration ) + { + TInt resId; + HBufC* format = NULL; + if ( aDuration >= KMPXOneHundredHoursInSecs ) + { + resId = R_MPX_TIME_DURAT_HHHMMSS_WITH_ZERO; + format = StringLoader::LoadLC( + resId, aDuration / KMPXOneHourInSeconds ); + } + else + { + resId = R_QTN_TIME_DURAT_MIN_SEC_WITH_ZERO; + if ( aDuration >= KMPXOneHourInSeconds ) + { + resId = R_QTN_TIME_DURAT_LONG_WITH_ZERO; + } + format = StringLoader::LoadLC( resId ); + } + + SetLayoutsL( aDuration > KMPXOneHourInSeconds? ETrue: EFalse); + + // Convert total playing time to texts. + TTime durTime( (TInt64)aDuration * KMPXOneSecInMicroSecs ); + + HBufC* buf = + HBufC::NewLC( format->Length() + KMPXDurationDisplayResvLen ); + TPtr bufTPtr( buf->Des() ); + + durTime.FormatL( bufTPtr, *format ); + AknTextUtils::LanguageSpecificNumberConversion( bufTPtr ); + CleanupStack::Pop( buf ); + CleanupStack::PopAndDestroy( format ); + + return buf; + } + +// --------------------------------------------------------------------------- +// From CCoeControl +// Draws the control. +// --------------------------------------------------------------------------- +// +void CMPXNotifierDialog::Draw( const TRect& /* aRect */ ) const + { + CWindowGc& gc = SystemGc(); + + MAknsSkinInstance* skin = AknsUtils::SkinInstance(); + MAknsControlContext* cc = AknsDrawUtils::ControlContext( this ); + + // background + AknsDrawUtils::Background( skin, cc, gc, Rect() ); + + // skin stuff - find out size of the corner piece + TAknLayoutRect cornerRect; + // skinned draw uses submenu popup window skin (skinned border) + cornerRect.LayoutRect( + Rect(), + SkinLayout::Submenu_skin_placing_Line_2() ); + + TRect innerRect( Rect() ); + innerRect.Shrink( cornerRect.Rect().Width(), cornerRect.Rect().Height() ); + + if ( !AknsDrawUtils::DrawFrame( + skin, + gc, + Rect(), + innerRect, + KAknsIIDQsnFrPopupSub, + KAknsIIDQsnFrPopupCenterSubmenu ) ) + { + // skinned border failed -> black border + gc.SetPenStyle( CGraphicsContext::ESolidPen ); + gc.SetBrushColor( KRgbBlack ); + gc.DrawRect( Rect() ); + } + } + +// --------------------------------------------------------------------------- +// From CCoeControl +// Handles a change to the control's resources. +// --------------------------------------------------------------------------- +// +void CMPXNotifierDialog::HandleResourceChange( TInt aType ) + { + CCoeControl::HandleResourceChange( aType ); + + if ( aType == KAknsMessageSkinChange ) + { + // Reload icons & layout + TRAP_IGNORE( + { + CreateIconsL(); + ShowIcon( iIconShown ); + SetLayoutsL(); + } ); + } + else if ( aType == KEikDynamicLayoutVariantSwitch ) + { + ResizeInfoPopup(); + if( iReopenDialog ) + { + MakeVisible( ETrue ); + iReopenDialog = EFalse; + } + } + else + { + // pass + } + } + +// --------------------------------------------------------------------------- +// From CCoeControl +// Responds to changes to the size and position of the contents of this +// control. +// --------------------------------------------------------------------------- +// +void CMPXNotifierDialog::SizeChanged() + { + TRAP_IGNORE( SetLayoutsL() ); + } + +// --------------------------------------------------------------------------- +// From CCoeControl +// Gets the number of controls contained in a compound control. +// --------------------------------------------------------------------------- +// +TInt CMPXNotifierDialog::CountComponentControls() const + { + return KMPXComponentsCount; + } + +// --------------------------------------------------------------------------- +// From CCoeControl +// Gets an indexed component of a compound control. +// --------------------------------------------------------------------------- +// +CCoeControl* CMPXNotifierDialog::ComponentControl( TInt aIndex ) const + { + CCoeControl* control = NULL; + + switch ( aIndex ) + { + case EMPXTrackLabel: + { + control = iSongLabel; + break; + } + case EMPXTimeLabel: + { + control = iTimeLabel; + break; + } + case EMPXPlayIcon: + { + control = iPlayIcon; + break; + } + case EMPXPauseIcon: + { + control = iPauseIcon; + break; + } + case EMPXFFIcon: + { + control = iFFIcon; + break; + } + case EMPXFRIcon: + { + control = iFRIcon; + break; + } + default: + { + // Pass + break; + } + } + + return control; + } + +// --------------------------------------------------------------------------- +// From MMPXPSKeyObserver +// Handle PS event +// --------------------------------------------------------------------------- +// +void CMPXNotifierDialog::HandlePSEvent( TUid aUid, TInt aKey ) + { + if ( ( aUid == KPSUidAiInformation ) && ( aKey == KActiveIdleState ) ) + { + //we want to cancel popup when going to active idle + CancelInfoPopup(); + } + } +// End of File