diff -r 41a7f70b3818 -r 5266b1f337bd phoneuis/dialer/src/cdialerkeypadcontainer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/phoneuis/dialer/src/cdialerkeypadcontainer.cpp Wed Sep 01 12:30:10 2010 +0100 @@ -0,0 +1,615 @@ +/* +* Copyright (c) 2007 - 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" +* 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: Shows number keypad and generates keypress event when +* buttons are pressed. +* +*/ + + +// INCLUDE FILES +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // for KDC_APP_RESOURCE_DIR +#include +#include +#include + +#include "cdialerkeypadcontainer.h" +#include "dialercommon.h" +#include "dialertrace.h" + +#include "cdialerkeypadbutton.h" + +// Number of buttons in this container +const TInt KNumberOfButtons = 12; + +struct TDialerButton + { + TMifDialer iBitmap; + TMifDialer iBitmapMask; + TInt iScanCode; + TInt iKeyCode; + }; + +const TDialerButton KKeyPadButtons[ KNumberOfButtons ] = + + { + { EMbmDialerQgn_indi_dialer_voicemail, + EMbmDialerQgn_indi_dialer_voicemail_mask, + '1', + '1' + }, + { KDialerNoIcon, KDialerNoIcon, + '2', '2' }, + { KDialerNoIcon, KDialerNoIcon, + '3', '3' }, + { KDialerNoIcon, KDialerNoIcon, + '4', '4' }, + { KDialerNoIcon, KDialerNoIcon, + '5', '5' }, + { KDialerNoIcon, KDialerNoIcon, + '6', '6' }, + { KDialerNoIcon, KDialerNoIcon, + '7', '7' }, + { KDialerNoIcon, KDialerNoIcon, + '8', '8' }, + { KDialerNoIcon, KDialerNoIcon, + '9', '9' }, + { KDialerNoIcon, KDialerNoIcon, + EStdKeyNkpAsterisk, '*' }, + { EMbmDialerQgn_indi_dialer_internet, + EMbmDialerQgn_indi_dialer_internet_mask, + '0', '0' }, + { KDialerNoIcon, KDialerNoIcon, + EStdKeyHash, '#' } + }; + + + +// ========================= MEMBER FUNCTIONS ================================ + +// --------------------------------------------------------------------------- +// Symbian OS two phased constructor +// --------------------------------------------------------------------------- +// +CDialerKeyPadContainer* CDialerKeyPadContainer::NewL( + const CCoeControl& aContainer, + TDialerOperationMode aOperatingMode + ) + { + CDialerKeyPadContainer* self = + new( ELeave )CDialerKeyPadContainer ( aContainer, aOperatingMode ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + + +// --------------------------------------------------------------------------- +// Symbian OS two phased constructor +// --------------------------------------------------------------------------- +// +void CDialerKeyPadContainer::ConstructL() + { + DIALER_PRINT("KeyPadContainer::ConstructL<"); + BaseConstructL(); + iKeyLabelManager = CDialerKeyPadLabelManager::NewL( *iCoeEnv, *this ); + CreateButtonsL(); + iCoeEnv->AddForegroundObserverL( *this ); + DIALER_PRINT("KeyPadContainer::ConstructL>"); + } + +// Constructor +CDialerKeyPadContainer::CDialerKeyPadContainer( + const CCoeControl& aContainer, + TDialerOperationMode aOperatingMode ) + : CDialerContainerBase ( + const_cast(aContainer) ), + iOperatingMode( aOperatingMode ) + { + } + +// Destructor +CDialerKeyPadContainer::~CDialerKeyPadContainer() + { + iButtons.ResetAndDestroy(); + iCoeEnv->RemoveForegroundObserver( *this ); + delete iKeyLabelManager; + } + +// --------------------------------------------------------------------------- +// CDialerKeyPadContainer::CountComponentControls +// +// --------------------------------------------------------------------------- +// +TInt CDialerKeyPadContainer::CountComponentControls() const + { + return KNumberOfButtons; + } + +// --------------------------------------------------------------------------- +// CDialerKeyPadContainer::ComponentControl +// +// --------------------------------------------------------------------------- +// +CCoeControl* CDialerKeyPadContainer::ComponentControl( TInt aIndex ) const + { + __ASSERT_DEBUG( aIndex < KNumberOfButtons, + _L("CDialerKeyPadContainer::ComponentControl, index out of range.")); + + return iButtons[aIndex]; + } + +// --------------------------------------------------------------------------- +// CDialerKeyPadContainer::HandlePointerEventL +// +// --------------------------------------------------------------------------- +// +void CDialerKeyPadContainer::HandlePointerEventL( + const TPointerEvent& aPointerEvent ) + { + DIALER_PRINT("KeyPadContainer::HandlePointerEventL<"); + + CCoeControl::HandlePointerEventL( aPointerEvent ); + + if ( aPointerEvent.iType == TPointerEvent::EButton1Down ) + { + iPointerEvent = aPointerEvent; + iKeyUpSimulatedDueToDragging = EFalse; + } + DIALER_PRINT("KeyPadContainer::HandlePointerEventL>"); + } + +// --------------------------------------------------------------------------- +// CDialerKeyPadContainer::SetVariety +// +// Set variety according to current state. +// --------------------------------------------------------------------------- +// +void CDialerKeyPadContainer::SetVariety() + { + if ( Layout_Meta_Data::IsLandscapeOrientation() ) + { + iVariety = EVideoVarietyLandscape; + } + else + { + iVariety = EVideoVarietyPortrait; + } + } + +// --------------------------------------------------------------------------- +// CDialerKeyPadContainer::SetLayout +// +// Set layout for video dtmf or phone dialer +// --------------------------------------------------------------------------- +// +void CDialerKeyPadContainer::SetLayout() + { + if ( iOperatingMode == EModeDialer || + iOperatingMode == EModeEasyDialing ) + { + // Same renewed layout is used regardless of the status + // of Easy Dialing + SetEasyDialingLayout(); + } + else + { + SetVideoLayout(); + } + } + +// --------------------------------------------------------------------------- +// CDialerKeyPadContainer::SetPhoneLayout +// +// --------------------------------------------------------------------------- +// +void CDialerKeyPadContainer::SetPhoneLayout() + { + // Set Number entry layout. + /* + + // LAF Table : grid_dialer2_keypad_pane + inline TAknLayoutScalableParameterLimits cell_dialer2_keypad_pane_ParamLimits() + inline TAknWindowComponentLayout cell_dialer2_keypad_pane() + + // LAF Table : cell_dialer2_keypad_pane + inline TAknLayoutScalableParameterLimits bg_button_pane_pane_cp04_ParamLimits() + inline TAknWindowComponentLayout bg_button_pane_pane_cp04() + inline TAknLayoutScalableParameterLimits cell_dialer2_keypad_pane_g1_ParamLimits() + */ + + TRect parentRect( Rect() ); + + // Layout buttons + TAknLayoutScalableParameterLimits limits = + AknLayoutScalable_Apps::cell_dialer2_keypad_pane_ParamLimits( iVariety ); + + TInt i = 0; + for ( TInt row = limits.FirstRow(); row <= limits.LastRow(); row++ ) + { + for ( TInt col = limits.FirstColumn(); + col <= limits.LastColumn(); col++ ) + { + iButtons[i]->SetVariety( iVariety ); + iButtons[i]->SetOperationMode( iOperatingMode ); + + AknLayoutUtils::LayoutControl( iButtons[i], parentRect, TAknWindowComponentLayout::Compose( + AknLayoutScalable_Apps::cell_dialer2_keypad_pane( iVariety, col, row ), + AknLayoutScalable_Apps::bg_button_pane_pane_cp04( iVariety ) ) ); + i++; + } + } + } + +// --------------------------------------------------------------------------- +// CDialerKeyPadContainer::SetEasyDialingLayout +// +// --------------------------------------------------------------------------- +// +void CDialerKeyPadContainer::SetEasyDialingLayout() + { + TRect parentRect( Rect() ); + + // Layout buttons + TAknLayoutScalableParameterLimits limits = + AknLayoutScalable_Apps::cell_dialer2_keypad_pane_ParamLimits( iVariety ); + + // Rectangle of the first button + TAknLayoutRect buttonLayoutRect; + buttonLayoutRect.LayoutRect( parentRect, + AknLayoutScalable_Apps::cell_dia3_key_num_pane( iVariety ) ); + TRect firstButtonRect = buttonLayoutRect.Rect(); + // Move the first button rect to top-left-corner of the keypad area, + // the default place is wrong in mirrored layout. + firstButtonRect.SetRect( parentRect.iTl, firstButtonRect.Size() ); + + TInt colCount = limits.LastColumn() - limits.FirstColumn() + 1; + + for ( TInt row = limits.FirstRow() ; row <= limits.LastRow() ; row++ ) + { + for ( TInt col = limits.FirstColumn() ; col <= limits.LastColumn() ; col++ ) + { + // Calculate corresponding index in iButtons array + TInt idx = col + row * colCount; + + // Set mode and variety so that correct button internal layout will be used. + // Always use ED mode, so that text labels are visible even when ED is off. + iButtons[idx]->SetVariety( iVariety ); + iButtons[idx]->SetOperationMode( EModeEasyDialing ); + + // Layout button + TRect buttonRect = firstButtonRect; + buttonRect.Move( col * buttonRect.Width(), row * buttonRect.Height() ); + buttonRect.Shrink( 1, 1 ); // to create small gap between buttons + iButtons[idx]->SetRect( buttonRect ); + } + } + + } + +// --------------------------------------------------------------------------- +// CDialerKeyPadContainer::SetVideoLayout +// +// --------------------------------------------------------------------------- +// +void CDialerKeyPadContainer::SetVideoLayout() + { + TRect parentRect( Rect() ); + + TAknLayoutScalableParameterLimits limits = + AknLayoutScalable_Apps::cell_video_dialer_keypad_pane_ParamLimits( iVariety ) ; + + TInt i = 0; + for ( TInt row = limits.FirstRow(); row <= limits.LastRow(); row++ ) + { + for ( TInt col = limits.FirstColumn(); + col <= limits.LastColumn(); + col++ ) + { + iButtons[i]->SetVariety( iVariety ); + iButtons[i]->SetOperationMode( iOperatingMode ); + + // Layout button + AknLayoutUtils::LayoutControl( + iButtons[i], parentRect, + TAknWindowComponentLayout::Compose( + AknLayoutScalable_Apps::cell_video_dialer_keypad_pane( + iVariety, col, row ), + AknLayoutScalable_Apps::bg_button_pane_cp08( iVariety ) ) ); + i++; + } + } + } + +// --------------------------------------------------------------------------- +// CDialerKeyPadContainer::CreateButtonsL +// +// Create buttons for this container. +// --------------------------------------------------------------------------- +// +void CDialerKeyPadContainer::CreateButtonsL() + { + DIALER_PRINT("KeyPadContainer::CreateButtonsL<"); + + TInt flags ( KAknButtonReportOnKeyDown | + KAknButtonRequestExitOnButtonUpEvent ); + + for ( TInt i = 0; i < KNumberOfButtons; i++ ) + { + const TPtrC numLabel = iKeyLabelManager->ButtonNumLabel( i ); + + const TPtrC alphaLabel = iKeyLabelManager->ButtonFirstAlphaLabel( i ); + + const TPtrC secondAlphaLabel = iKeyLabelManager->ButtonSecondAlphaLabel( i ); + + CDialerKeyPadButton* button = CDialerKeyPadButton::NewLC( + numLabel, + alphaLabel, + secondAlphaLabel, + KKeyPadButtons[i].iScanCode, + KKeyPadButtons[i].iKeyCode, + KKeyPadButtons[i].iBitmap, + KKeyPadButtons[i].iBitmapMask, + flags ); + iButtons.AppendL( button ); + CleanupStack::Pop( button ); + + button->SetMopParent( this ); + button->SetParent( this ); + button->SetContainerWindowL( *this ); + button->SetObserver( this ); + button->ActivateL(); + } + DIALER_PRINT("KeyPadContainer::CreateButtonsL>"); + } + +// --------------------------------------------------------------------------- +// CDialerKeyPadContainer::HandleControlEventL +// +// Handles an event from an observed button item. +// Finds the pressed button and generates key press event, which +// is handled by parent control. +// +// --------------------------------------------------------------------------- +// +void CDialerKeyPadContainer::HandleControlEventL( CCoeControl* aControl, + TCoeEvent aEventType ) + { + DIALER_PRINTF("KeyPadContainer::HandleControlEventL.EventType=", + (TInt)aEventType); + + if ( aEventType == EEventStateChanged || + aEventType == EEventRequestCancel || + aEventType == EEventRequestExit || + aEventType == CDialerKeyPadButton::EEventDraggingOutsideButton ) + + { + // Find tapped control + + CDialerKeyPadButton* tappedButton = NULL; + for ( TInt i=0; i < iButtons.Count(); i++ ) + { + if ( iButtons[i] == aControl ) + { + tappedButton = iButtons[i]; + break; + } + } + + if ( !tappedButton ) + { + __ASSERT_DEBUG( EFalse, DialerPanic( EDialerPanicEventFromUnknownControl ) ); + return; + } + + // Send key event to phone. + TKeyEvent keyEvent; + keyEvent.iCode = 0; // iCode should be 0 for all but EEventKey type of events + keyEvent.iScanCode = tappedButton->ScanCode(); + keyEvent.iModifiers = ( EModifierNumLock | EModifierKeypad ); // Mark that this event is dialer simulated + keyEvent.iRepeats = 0; + + switch ( aEventType ) + { + case EEventRequestExit: + case EEventRequestCancel: + { + DIALER_PRINT("HandleControlEventL.EEventRequestExit"); + iButtonPressedDown = EFalse; + if ( !iKeyUpSimulatedDueToDragging ) + { + ControlEnv()->SimulateKeyEventL( keyEvent, EEventKeyUp ); + } + iKeyUpSimulatedDueToDragging = EFalse; + } + break; + + case EEventStateChanged: + { + DIALER_PRINT("HandleControlEventL.EEventStateChanged"); + iButtonPressedDown = ETrue; + iParentControl.PrepareForFocusGainL(); + + ControlEnv()->SimulateKeyEventL( keyEvent, EEventKeyDown ); + + if ( iButtonPressedDown ) + { + // Send event key if key havent be lifted up already + keyEvent.iCode = tappedButton->KeyCode(); + ControlEnv()->SimulateKeyEventL( keyEvent, EEventKey ); + } + } + break; + + case CDialerKeyPadButton::EEventDraggingOutsideButton: + { + DIALER_PRINT("HandleControlEventL.EEventDraggingOutsideButton"); + // User hasn't released touch yet but in order to cancel + // long press action handled and initiated by parent control, + // we must send key up event now. + if ( !iKeyUpSimulatedDueToDragging ) + { + ControlEnv()->SimulateKeyEventL( keyEvent, EEventKeyUp ); + iKeyUpSimulatedDueToDragging = ETrue; + } + } + break; + + default: + break; + } + } + DIALER_PRINT("KeyPadContainer::HandleControlEventL>"); + } + +// --------------------------------------------------------------------------- +// CDialerKeyPadContainer::HandleResourceChange +// +// Forwards skin change event to buttons +// +// --------------------------------------------------------------------------- +// +void CDialerKeyPadContainer::HandleResourceChange( TInt aType ) + { + if ( aType == KAknsMessageSkinChange ) + { + for ( TInt i=0; i < iButtons.Count(); i++ ) + { + iButtons[i]->HandleResourceChange( aType ); + } + } + } + +// --------------------------------------------------------------------------- +// CDialerKeyPadContainer::MakeVisible +// +// Called when dialer control becomes visible or invisible +// +// --------------------------------------------------------------------------- +// +void CDialerKeyPadContainer::MakeVisible( TBool aVisible ) + { + // This is needed when dialer control disappeares during keypress. + // Last pressed pointer event must be forwarted to framework + // as pointer up event. Thus button is set to unpressed state etc. + // This code calls HandlePointerEventL of the parent class instead of this. + // If we call this classes HandlePointerEventL, this classes + // grab status is not cleared, and later coming EButton1Up events may end + // up erroneously to this class, although intended elsewhere. + // + if ( !aVisible && iButtonPressedDown && Parent() ) + { + iPointerEvent.iType = TPointerEvent::EButton1Up; + TRAP_IGNORE( Parent()->HandlePointerEventL( iPointerEvent ) ); + } + CCoeControl::MakeVisible( aVisible ); + } + +// --------------------------------------------------------------------------- +// CDialerKeyPadContainer::SetOperationMode +// +// Set new operation mode for the keypad +// +// --------------------------------------------------------------------------- +// +void CDialerKeyPadContainer::SetOperationMode( TDialerOperationMode aOperatingMode ) + { + iOperatingMode = aOperatingMode; + } + +// --------------------------------------------------------------------------- +// CDialerKeyPadContainer::HandleGainingForeground +// +// +// --------------------------------------------------------------------------- +// +void CDialerKeyPadContainer::HandleGainingForeground() + { + + } + +// --------------------------------------------------------------------------- +// CDialerKeyPadContainer::HandleLosingForeground +// +// +// --------------------------------------------------------------------------- +// +void CDialerKeyPadContainer::HandleLosingForeground() + { + // This is needed when dialer control disappeares during keypress. + // Last pressed pointer event must be forwarted to framework + // as pointer up event. Thus button is set to unpressed state etc. + // This code calls HandlePointerEventL of the parent class instead of this. + // If we call this classes HandlePointerEventL, this classes + // grab status is not cleared, and later coming EButton1Up events may end + // up erroneously to this class, although intended elsewhere. + // + if ( iButtonPressedDown && Parent() ) + { + iPointerEvent.iType = TPointerEvent::EButton1Up; + TRAP_IGNORE( Parent()->HandlePointerEventL( iPointerEvent ) ); + } + } + +// --------------------------------------------------------------------------- +// CDialerKeyPadContainer::KeyLabelsChanged +// +// Reset button labels and update the layout +// --------------------------------------------------------------------------- +// +void CDialerKeyPadContainer::KeyLabelsChanged() + { + for ( TInt i = 0 ; i < iButtons.Count() ; i++ ) + { + const TPtrC numLabel = iKeyLabelManager->ButtonNumLabel( i ); + const TPtrC alphaLabel = iKeyLabelManager->ButtonFirstAlphaLabel( i ); + const TPtrC secondAlphaLabel = iKeyLabelManager->ButtonSecondAlphaLabel( i ); + + iButtons[i]->SetNumLabel( numLabel ); + iButtons[i]->SetPrimaryAlphaLabel( alphaLabel ); + iButtons[i]->SetSecondaryAlphaLabel( secondAlphaLabel ); + + // reset layout + iButtons[i]->SetSize( iButtons[i]->Size() ); + } + DrawDeferred(); + } + +// --------------------------------------------------------------------------- +// CDialerKeyPadContainer::EnableTactileFeedback +// +// +// --------------------------------------------------------------------------- +// +void CDialerKeyPadContainer::EnableTactileFeedback( const TBool aEnable ) + { + for ( TInt i=0; i < iButtons.Count(); i++ ) + { + iButtons[i]->EnableAudioFeedback( aEnable ); + } + + } +// End of File