--- /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 <e32event.h>
+#include <gulicon.h>
+#include <eikapp.h>
+#include <aknbutton.h>
+#include <AknControl.h>
+#include <AknsUtils.h>
+#include <AknsSkinInstance.h>
+#include <AknsDrawUtils.h>
+#include <AknsConstants.h>
+#include <AknLayout2Def.h>
+#include <aknlayoutscalable_apps.cdl.h>
+#include <layoutmetadata.cdl.h>
+#include <data_caging_path_literals.hrh> // for KDC_APP_RESOURCE_DIR
+#include <touchfeedback.h>
+#include <aknlayoutscalable_avkon.cdl.h>
+#include <AknsFrameBackgroundControlContext.h>
+
+#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<CCoeControl&>(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