--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/uifw/AvKon/src/Aknvolumecontrol.cpp Tue Feb 02 01:00:49 2010 +0200
@@ -0,0 +1,2723 @@
+/*
+* Copyright (c) 2002-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: Volume editor class
+*
+*/
+
+
+// INCLUDE FILES
+#include "Aknvolumecontrol.h"
+#include <gulicon.h>
+#include <AknPanic.h>
+#include <AknNaviObserver.h>
+#include <AknUtils.h>
+#include <barsread.h>
+#include <AknStatuspaneUtils.h>
+#include <aknnavide.h>
+#include <AknsDrawUtils.h>
+#include <AknsFrameBackgroundControlContext.h>
+#include <aknappui.h>
+#include <aknconsts.h>
+#include <aknlayoutscalable_avkon.cdl.h>
+#include <skinlayout.cdl.h>
+#include <avkon.mbg>
+#include <AknVolumePopup.h>
+
+#include <AknTasHook.h>
+#include <touchfeedback.h>
+#include <aknlayoutscalable_apps.cdl.h>
+// CONSTANTS
+const TInt KVolumeMinValue = 1;
+const TInt KVolumeMaxValue = 10;
+const TInt KVolumeLevels = 10;
+
+const TInt KVolumeButtonDown = 0x01;
+const TInt KVolumeNaviPaneMuted = 0x02;
+const TInt KVolumeStepChange = 0x04;
+const TInt KVolumeLevelNotFound = 0;
+const TInt KVolumeLevelMuteTapped = 2000;
+
+const TInt KVolumeNaviPaneMutedValue = 0;
+
+// Define the loaded icon types - this affects drawing.
+const TInt KGfxModeNotLoaded = 0;
+const TInt KGfxModeNew = 1;// 1 slider type icon (+mask)
+const TInt KGfxModeOld = 2;// 10 ball icons, one for each volume level (+masks)
+const TInt KScrollRepeatTimeout = 250000; // 0.25 seconds
+// ----------------------------------------------------------------------------
+// Extension class
+//
+// ----------------------------------------------------------------------------
+//
+NONSHARABLE_CLASS(CVolumeExtension) : public CBase
+ {
+ public:
+ CVolumeExtension();
+ ~CVolumeExtension();
+
+ // Methods for svg drawing
+ static TBool UseSvgDrawing();
+ void DeleteBitmaps();
+ void SetIconSizes( TInt aStyle, const TRect& aParent ) const;
+
+ void LoadBitmapsL( TInt aStyle, const TRect& aParent );
+
+ // Sub-methods used by LoadBitmapsL
+ void TryLoadBitmapsSkinnedL( MAknsSkinInstance* aSkin );
+ void TryLoadBitmapsDefaultLargeL( MAknsSkinInstance* aSkin );
+ void TryLoadBitmapsDefaultSmallL( MAknsSkinInstance* aSkin );
+ void TryLoadBitmapsNoSkinL();
+
+ void CalculateParentRect( TInt aStyle, const TRect& aParent );
+ void DrawSvgSmallVolume( TInt aStyle, const TRect& aRect,
+ CBitmapContext& aGc, TInt aValue );
+ void DrawSvgSettingsVolume( const TRect& aRect,
+ CWindowGc& aGc, TInt aValue );
+ static void CreateSvgSettingsIconL( const TRect& aRect,
+ TInt aValue,
+ CGulIcon* aIcon );
+ static void CreateDynRangeStyleSettingsIconL( const TRect& aRect,
+ TInt aValue,
+ CGulIcon* aIcon,
+ TInt aMinimum,
+ TInt aMaximum );
+
+ void DrawSvgSettingsIconL( const TRect& aRect,
+ TInt aValue,
+ CGulIcon* aIcon );
+ void DrawDynRangeStyleSettingsIconL( const TRect& aRect,
+ TInt aValue,
+ CGulIcon* aIcon,
+ TInt aMinimum,
+ TInt aMaximum );
+
+ TInt GetVolumeLevelByPosition( const TInt& aStyle,
+ const TPoint& aPoint,
+ const TRect& aAreaRect ) const;
+
+ TRect RectFromLayout( const TRect& aParent,
+ const TAknWindowComponentLayout& aComponentLayout
+ ) const;
+
+ CFbsBitmap* iActiveIcons[KVolumeLevels];
+ CFbsBitmap* iInActiveIcons[KVolumeLevels];
+ CFbsBitmap* iActiveMasks[KVolumeLevels];
+ CFbsBitmap* iInActiveMasks[KVolumeLevels];
+
+ TRect iParentRect; // Volume indicator area
+ TRect iMuteRect; // Mute indicator rect for tapping
+
+ TRect iVolumeLevels[ KVolumeLevels ]; // Deprecated
+ TInt iFlags;
+
+ // Volume icons will be loaded the first time they are drawn,
+ // not when the control is constructed.
+ TBool iHasBeenDrawn;
+ TFileName iBmpFilename;
+ TInt iBmpId;
+ TInt iBmpMask;
+
+ CPeriodic* iTimer;
+ TInt iEffectTimerCount;
+ TInt iAnimatedEffectValue;
+
+ TInt iStoredLevel;
+
+ // For hi-res volume control implementation
+ TInt iMinimumValue;
+ TInt iMaximumValue;
+ TInt iGfxMode; // Defines which icons are loaded when drawing
+ TInt iOldScaleSettingVolume; // for 9 step setting volume
+
+ /**
+ * Flag to define whether or not this control is topmost on the navi pane's
+ * control stack.
+ */
+ TBool iIsOnNaviStack;
+ TInt iOldLevel;
+ TBool iReduce;
+
+ TBool iNoDraw;
+ TBool iGrabPoint;
+
+ /**
+ * Extended touch area used
+ */
+ TBool iUseExtendedTouchArea;
+
+ /**
+ * Touch area
+ */
+ TRect iTouchArea;
+ };
+
+// ----------------------------------------------------------------------------
+// CAknVolumeControl::CAknVolumeControl()
+// Default constructor.
+// ----------------------------------------------------------------------------
+//
+EXPORT_C CAknVolumeControl::CAknVolumeControl()
+ {
+ AKNTASHOOK_ADD( this, "CAknVolumeControl" );
+ }
+
+// ----------------------------------------------------------------------------
+// CAknVolumeControl::~CAknVolumeControl()
+// Destructor.
+// ----------------------------------------------------------------------------
+//
+EXPORT_C CAknVolumeControl::~CAknVolumeControl()
+ {
+ AKNTASHOOK_REMOVE();
+ AknsUtils::DeregisterControlPosition( this );
+ delete iBitmap;
+ delete iMaskBitmap;
+ delete iExtension;
+ }
+
+// ----------------------------------------------------------------------------
+// CAknVolumeControl::SetValue(TInt aValue)
+// Sets the value.
+// ----------------------------------------------------------------------------
+//
+EXPORT_C void CAknVolumeControl::SetValue( TInt aValue )
+ {
+ // NOTE: In settings page layouts (EDynRangeSettingsVolumeControl)
+ // using dynamic min and max values defined in the resource file. The
+ // values cannot be checked in SetValue() because SetValue() is called
+ // before ConstructFromResource() which actually reads the min and max
+ // values as well as the default value even though it is also given in
+ // the settings page constructor parameter.
+ //
+ if ( !iExtension )
+ {
+ return;
+ }
+
+ TBool valueChanged( aValue != iValue );
+
+ switch( iStyle )
+ {
+ case EDynRangeSettingsVolumeControl:
+ case EDynRangeNaviPaneVolumeControl:
+ // Do not check EDynRangeSettingsVolumeControl because it's value
+ // might be set before the actual min and max are read from the
+ // resource (settings page feature).
+ // Navi pane's EDynRangeNaviPaneVolumeControl is also ignored.
+ break;
+ default:
+ __ASSERT_DEBUG( aValue >= iExtension->iMinimumValue &&
+ aValue <= iExtension->iMaximumValue,
+ Panic( EAknPanicOutOfRange ) );
+ }
+
+ iValue = aValue;
+
+ if ( iExtension )
+ {
+ iExtension->iFlags &= ~KVolumeNaviPaneMuted;
+ }
+
+ if ( iStyle == ENaviPaneVolumeControl ||
+ iStyle == EDynRangeNaviPaneVolumeControl )
+ {
+ TInt event = MAknNavigationObserver::ENaviEventHandleNavigation;
+ if ( iValue <= iExtension->iMinimumValue )
+ {
+ event=MAknNavigationObserver::ENaviEventLeftMostItemReached;
+ if ( iValue == iExtension->iMinimumValue )
+ {
+ iExtension->iFlags |= KVolumeNaviPaneMuted;
+ }
+ }
+ else if ( iExtension->iMaximumValue == iValue )
+ {
+ event = MAknNavigationObserver::ENaviEventRightMostItemReached;
+ }
+
+ TRAP_IGNORE(
+ ReportEventL(
+ STATIC_CAST( MCoeControlObserver::TCoeEvent, event ) ) );
+
+ if ( valueChanged )
+ {
+ TRAP_IGNORE(
+ ReportEventL(
+ MCoeControlObserver::EEventStateChanged ) );
+ }
+
+ SetVolumeLayout( iStyle );
+ if ( !iExtension->iNoDraw )
+ {
+ DrawNow();
+ }
+
+ // Volume popup is used instead of navi pane volume control,
+ // pass the new value also to the popup.
+ CAknVolumePopup* parent = static_cast<CAknVolumePopup*> ( Parent() );
+ if ( parent && parent->ComponentControl( 5 ) == this )
+ {
+ if ( valueChanged )
+ {
+ parent->SetValue( aValue );
+ }
+
+ if ( iExtension->iIsOnNaviStack && ( valueChanged ||
+ aValue == iExtension->iMinimumValue ||
+ aValue == iExtension->iMaximumValue ) )
+ {
+ // Show the popup only if status pane is visible
+ // to maintain same kind of functionality as in
+ // navi pane volume control.
+ CEikStatusPaneBase* sp = CEikStatusPaneBase::Current();
+ if ( sp && sp->IsVisible() )
+ {
+ TRAP_IGNORE( parent->ShowVolumePopupL() );
+ }
+ }
+ }
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CAknVolumeControl::Value() const
+// Returns the value.
+// ----------------------------------------------------------------------------
+//
+EXPORT_C TInt CAknVolumeControl::Value() const
+ {
+ return iValue;
+ }
+
+// ----------------------------------------------------------------------------
+// CAknVolumeControl::SetRange()
+//
+// ----------------------------------------------------------------------------
+//
+EXPORT_C void CAknVolumeControl::SetRange( TInt aMinimumValue,
+ TInt aMaximumValue )
+ {
+ TBool rangeChanged( aMinimumValue != iExtension->iMinimumValue ||
+ aMaximumValue != iExtension->iMaximumValue );
+
+ __ASSERT_DEBUG( aMinimumValue < aMaximumValue,
+ Panic( EAknPanicInvalidValue ) );
+ if ( iExtension )
+ {
+ iExtension->iMinimumValue = aMinimumValue;
+ iExtension->iMaximumValue = aMaximumValue;
+ }
+
+ // disable old volume control scaling
+ if(iExtension->iOldScaleSettingVolume)
+ {
+ iExtension->iOldScaleSettingVolume = EFalse;
+ }
+
+ if ( iExtension->iIsOnNaviStack )
+ {
+ // Volume popup is used instead of navi pane volume control,
+ // pass the new range also to the popup.
+ CAknVolumePopup* parent = static_cast<CAknVolumePopup*> ( Parent() );
+
+ if ( parent && parent->ComponentControl( 5 ) == this )
+ {
+ if ( rangeChanged )
+ {
+ parent->SetRange( aMinimumValue, aMaximumValue );
+ }
+ }
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CAknVolumeControl::GetRange()
+//
+// ----------------------------------------------------------------------------
+//
+EXPORT_C void CAknVolumeControl::GetRange( TInt& aMinimumValue,
+ TInt& aMaximumValue )
+ {
+ if ( iExtension )
+ {
+ aMinimumValue = iExtension->iMinimumValue;
+ aMaximumValue = iExtension->iMaximumValue;
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CAknVolumeControl::CreateBitmapL()
+//
+// ----------------------------------------------------------------------------
+//
+EXPORT_C CFbsBitmap* CAknVolumeControl::CreateBitmapL(TInt aValue)
+ {
+ CGulIcon* icon =
+ CreateSetStyleListBoxIconL( aValue ); // now have ownership
+ icon->SetBitmapsOwnedExternally( ETrue );
+ CFbsBitmap* bitmap = icon->Bitmap();
+ CFbsBitmap* mask = icon->Mask();
+ delete icon;
+ delete mask;
+ return bitmap; // Ownership transferred
+ }
+
+// ----------------------------------------------------------------------------
+// CAknVolumeControl::CreateSetStyleListBoxIconL()
+// Draw volume control in setting list item
+// ----------------------------------------------------------------------------
+//
+EXPORT_C CGulIcon* CAknVolumeControl::CreateSetStyleListBoxIconL( TInt aValue )
+ {
+
+ // Make the icon and put it in the array
+ CGulIcon* icon = CGulIcon::NewLC();
+
+ TRect origin;
+ AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EMainPane, origin );
+
+ TAknLayoutRect layoutRect;
+ layoutRect.LayoutRect(origin,
+ AknLayoutScalable_Avkon::listscroll_gen_pane(0));
+ layoutRect.LayoutRect(layoutRect.Rect(),
+ AknLayoutScalable_Avkon::list_gen_pane(0));
+ layoutRect.LayoutRect(layoutRect.Rect(),
+ AknLayoutScalable_Avkon::list_setting_number_pane(0));
+ layoutRect.LayoutRect(layoutRect.Rect(),
+ AknLayoutScalable_Avkon::set_value_pane(0));
+ layoutRect.LayoutRect(layoutRect.Rect(),
+ AknLayoutScalable_Avkon::volume_small_pane_cp());
+ TRect rect(layoutRect.Rect());
+
+ // Move to 0,0
+ rect.Move(-rect.iTl.iX,-rect.iTl.iY);
+
+ CVolumeExtension::CreateSvgSettingsIconL( rect, aValue, icon );
+
+ CleanupStack::Pop( icon ); // icon - not owned anymore, do not destroy
+
+ return icon; // Ownership transferred
+ }
+
+// ----------------------------------------------------------------------------
+// CAknVolumeControl::CreateScalableListBoxIconL()
+// Draw a scalable volume control in setting list item
+// ----------------------------------------------------------------------------
+//
+EXPORT_C CGulIcon* CAknVolumeControl::CreateSetDynRangeStyleListBoxIconL(
+ TInt aValue,
+ TInt aMinimum,
+ TInt aMaximum )
+ {
+
+
+ // Make the icon and put it in the array
+ CGulIcon* icon = CGulIcon::NewLC();
+
+ TRect origin;
+ AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EMainPane, origin );
+
+ TAknLayoutRect layoutRect;
+ layoutRect.LayoutRect(origin,
+ AknLayoutScalable_Avkon::listscroll_gen_pane(0));
+ layoutRect.LayoutRect(layoutRect.Rect(),
+ AknLayoutScalable_Avkon::list_gen_pane(0));
+ layoutRect.LayoutRect(layoutRect.Rect(),
+ AknLayoutScalable_Avkon::list_setting_number_pane(0));
+ layoutRect.LayoutRect(layoutRect.Rect(),
+ AknLayoutScalable_Avkon::set_value_pane(0));
+ layoutRect.LayoutRect(layoutRect.Rect(),
+ AknLayoutScalable_Avkon::volume_small_pane_cp());
+ TRect rect(layoutRect.Rect());
+
+ // Move to 0,0
+ rect.Move(-rect.iTl.iX,-rect.iTl.iY);
+
+ CVolumeExtension::CreateDynRangeStyleSettingsIconL( rect, aValue, icon,
+ aMinimum, aMaximum );
+
+ CleanupStack::Pop( icon ); // icon - not owned anymore, do not destroy
+
+ return icon; // Ownership transferred
+ }
+
+
+// ----------------------------------------------------------------------------
+// CAknVolumeControl::HandleNaviStackChange()
+// ----------------------------------------------------------------------------
+//
+void CAknVolumeControl::HandleNaviStackChange( TBool aIsOnNaviStack )
+ {
+ if ( iExtension )
+ {
+ iExtension->iIsOnNaviStack = aIsOnNaviStack;
+ }
+ }
+
+
+// ----------------------------------------------------------------------------
+// CAknVolumeControl::MinimumSize()
+// Returns the size.
+// ----------------------------------------------------------------------------
+//
+TSize CAknVolumeControl::MinimumSize()
+ {
+ TAknLayoutRect layout;
+ if ( iStyle == ENaviPaneVolumeControl )
+ {
+ if ( AknStatuspaneUtils::SmallLayoutActive() )
+ {
+ layout.LayoutRect( Rect(),
+ AknLayoutScalable_Avkon::volume_small2_pane() );
+ }
+ else
+ {
+ layout.LayoutRect( Rect(),
+ AknLayoutScalable_Avkon::volume_small_pane() );
+ }
+
+ return layout.Rect().Size();
+ }
+ else // Setting Page & Popup volume control
+ {
+ return Rect().Size();
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CAknVolumeControl::OfferKeyEventL
+// Handles the key events.
+// ----------------------------------------------------------------------------
+//
+TKeyResponse CAknVolumeControl::OfferKeyEventL( const TKeyEvent& aKeyEvent,
+ TEventCode aType )
+ {
+ if ( aType == EEventKey )
+ {
+ TInt volumeValue = Value();
+ switch( aKeyEvent.iCode )
+ {
+ case EKeyLeftArrow:
+ {
+ if (volumeValue > iExtension->iMinimumValue)
+ {
+ volumeValue--;
+ SetValue( volumeValue );
+ if ( iStyle != EDynRangePopupVolumeControl &&
+ !iExtension->iNoDraw )
+ {
+ DrawNow();
+ }
+ ReportEventL( MCoeControlObserver::EEventStateChanged );
+ }
+ else
+ {
+ CAknVolumePopup* parent =
+ static_cast<CAknVolumePopup*> ( Parent() );
+ if ( iExtension &&
+ iExtension->iIsOnNaviStack &&
+ parent &&
+ parent->ComponentControl( 5 ) == this )
+ {
+ // Show the volume popup even if volume level is not changed
+ // to indicate that a volume adjustment key event has been
+ // received.
+ CEikStatusPaneBase* sp = CEikStatusPaneBase::Current();
+ if ( sp && sp->IsVisible() )
+ {
+ // Show the popup only if status pane is visible
+ // to maintain same kind of functionality as in
+ // navi pane volume control.
+ parent->ShowVolumePopupL();
+ }
+ }
+
+ if ( iStyle != ESettingsVolumeControl )
+ {
+ TInt event = MAknNavigationObserver::ENaviEventLeftMostItemReached;
+ ReportEventL(
+ STATIC_CAST( MCoeControlObserver::TCoeEvent, event ) );
+ }
+#ifdef RD_ANIMATION_EFFECTS
+ else if (iExtension && (iExtension->iGfxMode == KGfxModeOld))
+ {
+ // only with old volume graphics
+ StartTimerL();
+ }
+#endif
+ }
+
+ return EKeyWasConsumed;
+ }
+ case EKeyRightArrow:
+ {
+ if ( iExtension && (volumeValue < iExtension->iMaximumValue) )
+ {
+ volumeValue++;
+ SetValue( volumeValue );
+ if ( iStyle != EDynRangePopupVolumeControl &&
+ !iExtension->iNoDraw )
+ {
+ DrawNow();
+ }
+ ReportEventL( MCoeControlObserver::EEventStateChanged );
+ }
+ else
+ {
+ CAknVolumePopup* parent =
+ static_cast<CAknVolumePopup*> ( Parent() );
+ if ( iExtension &&
+ iExtension->iIsOnNaviStack &&
+ parent &&
+ parent->ComponentControl( 5 ) == this )
+ {
+ // Show the volume popup even if volume level is not changed
+ // to indicate that a volume adjustment key event has been
+ // received.
+ CEikStatusPaneBase* sp = CEikStatusPaneBase::Current();
+ if ( sp && sp->IsVisible() )
+ {
+ // Show the popup only if status pane is visible
+ // to maintain same kind of functionality as in
+ // navi pane volume control.
+ parent->ShowVolumePopupL();
+ }
+ }
+
+ if ( iStyle != ESettingsVolumeControl )
+ {
+ TInt event = MAknNavigationObserver::ENaviEventRightMostItemReached;
+ ReportEventL(
+ STATIC_CAST( MCoeControlObserver::TCoeEvent, event ) );
+ }
+#ifdef RD_ANIMATION_EFFECTS
+ else if (iExtension && iExtension->iGfxMode == KGfxModeOld)
+ {
+ // only with old volume graphics
+ StartTimerL();
+ }
+#endif
+ }
+
+ return EKeyWasConsumed;
+ }
+ default:
+ break;
+ }
+ }
+ return EKeyWasNotConsumed;
+ }
+
+// ----------------------------------------------------------------------------
+// CAknVolumeControl::ConstructFromResourceL(TResourceReader& aReader)
+// Basic construct from the resource function.
+// ----------------------------------------------------------------------------
+//
+EXPORT_C void CAknVolumeControl::ConstructFromResourceL(
+ TResourceReader& aReader)
+ {
+ TBool newResourceStructUsed = EFalse;
+
+ iStyle=aReader.ReadInt16();
+
+ if(iStyle == -1) // 0xfffffff
+ {
+ newResourceStructUsed = ETrue;
+ iStyle=aReader.ReadInt16();
+ }
+
+ if (iStyle == ESmallPopupVolumeControl ||
+ iStyle == ESmallPopupVolumeControlWithPercent )
+ {
+ iStyle = EDynRangePopupVolumeControl;
+ }
+ __ASSERT_ALWAYS( iStyle == ESettingsVolumeControl
+ || iStyle == ENaviPaneVolumeControl
+ || iStyle == EPopupVolumeControl
+ || iStyle == EDynRangeSettingsVolumeControl
+ || iStyle == EDynRangeNaviPaneVolumeControl
+ || iStyle == EDynRangePopupVolumeControl,
+ Panic( EAknPanicOutOfRange ) );
+
+ iExtension = new(ELeave) CVolumeExtension;
+ iExtension->iTimer = CPeriodic::NewL( CActive::EPriorityStandard );
+
+ TInt value = aReader.ReadInt16();
+
+
+ TPtrC bmpFile=aReader.ReadTPtrC();
+ TFileName filename( bmpFile );
+ CompleteWithAppPath( filename );
+ TInt bmpId=aReader.ReadInt16();
+ TInt bmpMask=aReader.ReadInt16();
+
+ if ( iStyle != ESettingsVolumeControl )
+ {
+ iExtension->iBmpFilename = filename;
+ iExtension->iBmpId = bmpId;
+ iExtension->iBmpMask = bmpMask;
+
+ CreateNaviIconL();
+ // Rest of the volume icons will be loaded later.
+ }
+
+ // Read default min and max volume values from new VOLUME struct used by
+ // new hi-res volume layout resources. These are not defined in older
+ // layout resources so do not read these in this case.
+ if( newResourceStructUsed )
+ {
+ iExtension->iMinimumValue = aReader.ReadInt16();
+ iExtension->iMaximumValue = aReader.ReadInt16();
+ __ASSERT_DEBUG( iExtension->iMinimumValue < iExtension->iMaximumValue,
+ Panic( EAknPanicInvalidValue ) );
+
+ }
+ // setting volume, also dyn range uses 1-10 scale if using old struct
+ else if(iStyle == ESettingsVolumeControl || iStyle == EDynRangeSettingsVolumeControl)
+ {
+ // set scaled value calculation to note the old 1-10 scale with 10 graphics
+ iExtension->iOldScaleSettingVolume = ETrue;
+ iExtension->iMinimumValue = KVolumeMinValue;
+ iExtension->iMaximumValue = KVolumeMaxValue;
+ }
+ else
+ {
+ iExtension->iMinimumValue = KVolumeNaviPaneMutedValue;
+ iExtension->iMaximumValue = KVolumeMaxValue;
+ }
+
+ if ( iStyle == EPopupVolumeControl)
+ {
+ iStyle = EDynRangePopupVolumeControl;
+ }
+ // SetValue checks iMinimumValue and iMaximumValue which must be read before this
+ SetValue( value );
+ }
+
+// ----------------------------------------------------------------------------
+// CAknVolumeControl::SizeChanged()
+// Sets the layout.
+// ----------------------------------------------------------------------------
+//
+void CAknVolumeControl::SizeChanged()
+ {
+ AknsUtils::RegisterControlPosition( this );
+ SetVolumeLayout( iStyle );
+ if ( AknLayoutUtils::PenEnabled()&&
+ iExtension &&
+ !iExtension->iGrabPoint )
+ {
+ // Enable drag events, it will then be possible to drag from thumb
+ EnableDragEvents();
+
+ //Enable dragging to start from thumb and then move outside the slider
+ DrawableWindow()->SetPointerGrab( ETrue );
+
+ iExtension->iGrabPoint = ETrue;
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CAknVolumeControl::SetVolumeLayout(TInt aStyle)
+// Pure layout function.
+// ----------------------------------------------------------------------------
+//
+void CAknVolumeControl::SetVolumeLayout( TInt aStyle )
+ {
+ TAknLayoutRect layout;
+ TRect rect(Rect());
+ TRect parentRect( Rect() );
+
+ switch ( aStyle )
+ {
+ case ESettingsVolumeControl:
+ {
+ layout.LayoutRect( rect,
+ AknLayoutScalable_Avkon::volume_set_pane_g1() );
+ iStartPos = layout.Rect().iTl;
+
+ if ( iExtension )
+ {
+ iExtension->CalculateParentRect( aStyle, rect );
+ UseExtendedTouchArea();
+ return;
+ }
+ }
+ break;
+
+ case ENaviPaneVolumeControl:
+ case EDynRangeNaviPaneVolumeControl:
+ {
+ MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+ TRgb color;
+ AknsUtils::GetCachedColor( skin, color, KAknsIIDQsnIconColors,
+ EAknsCIQsnIconColorsCG7 );
+ TRAP_IGNORE ( CreateNaviIconL() );
+ if (AknStatuspaneUtils::StaconPaneActive())
+ {
+ rect = CAknNavigationDecorator::DecoratedControlRect(
+ CAknNavigationDecorator::ENaviVolume );
+ layout.LayoutRect( rect,
+ AknLayoutScalable_Avkon::volume_small_pane() );
+ iStartPos = TPoint( layout.Rect().iTl.iX ,
+ layout.Rect().iTl.iY );
+ layout.LayoutRect( rect,
+ AknLayoutScalable_Avkon::navi_navi_volume_pane_g1() );
+ iBmpPos = TPoint( layout.Rect().iTl.iX ,
+ layout.Rect().iTl.iY );
+
+ }
+ else if (AknStatuspaneUtils::IdleLayoutActive())
+ {
+ layout.LayoutRect( rect,
+ AknLayoutScalable_Avkon::volume_small_pane() );
+ iStartPos = TPoint( layout.Rect().iTl.iX - rect.iTl.iX,
+ layout.Rect().iTl.iY );
+
+ layout.LayoutRect( rect,
+ AknLayoutScalable_Avkon::navi_navi_volume_pane_g1() );
+ iBmpPos = TPoint( layout.Rect().iTl.iX - rect.iTl.iX,
+ layout.Rect().iTl.iY );
+
+ }
+ else if ( AknStatuspaneUtils::SmallLayoutActive() )
+ {
+ //Get the volume strength indicator layout
+ layout.LayoutRect( rect,
+ AknLayoutScalable_Avkon::volume_small2_pane() );
+ //volume strength indicator start position
+ iStartPos = TPoint( layout.Rect().iTl.iX,
+ layout.Rect().iTl.iY );
+
+ //Bitmap layout
+ layout.LayoutRect( parentRect,
+ AknLayoutScalable_Avkon::status_small_volume_pane_g1()
+ );
+ iBmpPos = TPoint( layout.Rect().iTl.iX,
+ layout.Rect().iTl.iY );
+ }
+ else
+ {
+ layout.LayoutRect( rect,
+ AknLayoutScalable_Avkon::volume_small_pane() );
+ iStartPos = TPoint( layout.Rect().iTl.iX - rect.iTl.iX,
+ layout.Rect().iTl.iY );
+ layout.LayoutRect( rect,
+ AknLayoutScalable_Avkon::navi_navi_volume_pane_g1() );
+ iBmpPos = TPoint( layout.Rect().iTl.iX - rect.iTl.iX,
+ layout.Rect().iTl.iY );
+ }
+ if ( iBitmap != NULL )
+ {
+ AknIconUtils::SetIconColor( iBitmap, color );
+ AknIconUtils::SetSize(iBitmap, layout.Rect().Size());
+ if ( iExtension )
+ {
+ iExtension->iMuteRect = layout.Rect();
+ }
+ }
+ }
+ break;
+
+ case EPopupVolumeControl:
+ // just use given rect!
+ iStartPos = TPoint( rect.iTl.iX, rect.iTl.iY );
+ break;
+
+ default:
+ // does not happen
+ break;
+ }
+
+ if ( iExtension )
+ {
+ iExtension->CalculateParentRect( aStyle, parentRect );
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CAknVolumeControl::Draw(const TRect& aRect) const
+// Implementation of automatically called control drawing function from
+// CCoeControl.
+// ----------------------------------------------------------------------------
+//
+void CAknVolumeControl::Draw( const TRect& /*aRect*/ ) const
+ {
+ if ( iExtension->iNoDraw )
+ {
+ return;
+ }
+ /*
+ * If there are volume graphics in active skin, use those to be compatible
+ * with 2.6 skins, then check for svg graphics. If that fails, draw using
+ * legacy code
+ */
+ if ( iExtension && !iExtension->iHasBeenDrawn )
+ {
+ TRAP_IGNORE( iExtension->LoadBitmapsL( iStyle, Rect()
+ /*iAvkonAppUi->ApplicationRect() */));
+ iExtension->iHasBeenDrawn = ETrue;
+ }
+
+ if( iExtension && iExtension->iGfxMode == KGfxModeNew)
+ {
+ DrawDynRangeSettingsStyleVolumeControl( iExtension->iParentRect );
+ }
+ else if( iExtension )
+ {
+ switch( iStyle )
+ {
+ case ESettingsVolumeControl:
+ DrawSettingsStyleVolumeControl( Rect() );
+ break;
+ default:
+ if( AknsUtils::AvkonSkinEnabled() )
+ {
+ DrawSkinnedDefaultStyleVolumeControl( Rect() );
+ }
+ else
+ {
+ DrawDefaultStyleVolumeControl( Rect() );
+ }
+ break;
+ }
+ }
+
+ }
+
+// ----------------------------------------------------------------------------
+// CAknVolumeControl::DrawSettingsStyleVolumeControl
+//
+// ----------------------------------------------------------------------------
+//
+void CAknVolumeControl::DrawSettingsStyleVolumeControl( const TRect& aRect ) const
+ {
+ CWindowGc& gc=SystemGc();
+ MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+ MAknsControlContext* edCc = AknsDrawUtils::ControlContext( this );
+ AknsDrawUtils::Background( skin, edCc, this, gc, aRect );
+
+ gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
+ gc.SetPenStyle(CGraphicsContext::ENullPen);
+
+ if (AknsUtils::AvkonSkinEnabled() && iExtension)
+ {
+ gc.SetBrushStyle(CGraphicsContext::ENullBrush);
+ iExtension->DrawSvgSettingsVolume( iExtension->iParentRect,
+ gc,
+ ScaledValue() );
+ return;
+ }
+ else
+ {
+ //I'm not sure whether this branch is useless or not ,so I didn't delete this branch.
+ TInt colorIndex = 0;
+ for (TInt i=0; i < KVolumeLevels; i++) // there is ten bars
+ {
+ if ( i < ScaledValue() )
+ {
+ colorIndex = 1;
+ }
+ else
+ {
+ colorIndex = 0;
+ }
+ TRect rect = Rect();
+ TAknWindowLineLayout layout = AKN_LAYOUT_TABLE_Setting_volume_pane_elements_SUB_TABLE_0(i + 1, colorIndex);
+ TAknLayoutRect volumeBarLayout;
+ volumeBarLayout.LayoutRect(rect, layout);
+ if ( iExtension && AknLayoutUtils::PenEnabled() )
+ {
+ // Store rect for every level. We can then decide what level was clicked
+ iExtension->iVolumeLevels[i] = volumeBarLayout.Rect();
+ }
+ gc.SetBrushColor( volumeBarLayout.Color() );
+ gc.DrawRect( volumeBarLayout.Rect() );
+ }
+ }
+ }
+
+
+// ----------------------------------------------------------------------------
+// CAknVolumeControl::DrawDynRangeSettingsStyleVolumeControl
+//
+// ----------------------------------------------------------------------------
+//
+void CAknVolumeControl::DrawDynRangeSettingsStyleVolumeControl(
+ const TRect& aVolumeArea ) const
+ {
+ // !!! Assumptions used: Sizes of iExtension->iInActiveIcons[0],
+ // iExtension->iActiveIcons[0], corresponding masks and
+ // aVolumeArea are identical.
+ CWindowGc& gc=SystemGc();
+ if ( !Background() )
+ {
+ MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+ MAknsControlContext* edCc = AknsDrawUtils::ControlContext( this );
+
+ if ( iStyle != EDynRangePopupVolumeControl )
+ {
+ AknsDrawUtils::Background( skin, edCc, this, gc, aVolumeArea );
+ }
+ }
+ else
+ {
+ Background()->Draw( gc, *this, aVolumeArea );
+ }
+
+ // Only skin enabled version should exist
+ TRect iconRect(0,0, iExtension->iActiveIcons[0]->SizeInPixels().iWidth,
+ iExtension->iActiveIcons[0]->SizeInPixels().iHeight );
+
+ TRect activeRect;// rect area used for active volume slider icon
+ TRect inactiveRect;// rect area used for inactive volume slider icon
+
+ CalcVolumeIconAreas( Value(),
+ aVolumeArea,
+ activeRect,
+ inactiveRect );
+
+ // Area of the actual icon to be drawn in rect area
+ TRect activeIcon( 0, 0,
+ activeRect.iBr.iX - activeRect.iTl.iX,
+ activeRect.iBr.iY - activeRect.iTl.iY );
+
+ // Area of the actual icon to be drawn in rect area
+ TRect inactiveIcon( inactiveRect.iTl.iX - aVolumeArea.iTl.iX,
+ 0,
+ inactiveRect.iBr.iX - aVolumeArea.iTl.iX,
+ inactiveRect.iBr.iY - aVolumeArea.iTl.iY );
+
+ gc.BitBltMasked( activeRect.iTl,
+ iExtension->iActiveIcons[0],
+ activeIcon,
+ iExtension->iActiveMasks[0], ETrue );
+
+ gc.BitBltMasked( inactiveRect.iTl,
+ iExtension->iInActiveIcons[0],
+ inactiveIcon,
+ iExtension->iInActiveMasks[0], ETrue );
+ // Draw speaker or mute icon
+ if ( ( iBitmap != NULL ) && ( iMaskBitmap != NULL ) )
+ {
+ TRect bmpRect(TPoint(0,0),TSize(iBitmap->SizeInPixels()));
+ if (iStyle == EDynRangeNaviPaneVolumeControl) // popup handles icons itself
+ {
+ gc.BitBltMasked(iBmpPos, iBitmap, bmpRect, iMaskBitmap, ETrue);
+ }
+ }
+ }
+
+
+// ----------------------------------------------------------------------------
+// CAknVolumeControl::CalcVolumeIconAreas()
+//
+// ----------------------------------------------------------------------------
+//
+void CAknVolumeControl::CalcVolumeIconAreas( const TInt aVolume,
+ const TRect& aDrawArea,
+ TRect& aActiveRect,
+ TRect& aInactiveRect ) const
+ {
+ // Calculate drawing area split between active and inactive icon areas in percentage
+ // it is caculating the activeRatio by iOldScaleSettingVolume
+ // it is very important for drawing the volumecontrol
+ // because the tester requires there must be at least one piece of shadow in it,
+ // if we set the iMinimumValue not as (iMinimunValue+1) in HandlePointerEventL and
+ // draw the aActiveRect like this, all things go well.
+ TInt activeRatio;
+ if( !iExtension->iOldScaleSettingVolume )
+ {
+ activeRatio = ( aVolume - iExtension->iMinimumValue ) * 100
+ / ( iExtension->iMaximumValue - iExtension->iMinimumValue );
+ }
+
+ else
+ {
+ activeRatio = aVolume * 10;
+ }
+ aActiveRect.iTl.iX = aDrawArea.iTl.iX;
+ aActiveRect.iTl.iY = aDrawArea.iTl.iY;
+ aActiveRect.iBr.iX = aDrawArea.iTl.iX + ( aDrawArea.iBr.iX - aDrawArea.iTl.iX ) * activeRatio / 100;
+ aActiveRect.iBr.iY = aDrawArea.iBr.iY;
+
+ aInactiveRect.iTl.iX = aActiveRect.iBr.iX /*+ 1*/;
+ aInactiveRect.iTl.iY = aDrawArea.iTl.iY;
+ aInactiveRect.iBr.iX = aDrawArea.iBr.iX;
+ aInactiveRect.iBr.iY = aDrawArea.iBr.iY;
+ }
+
+
+// ----------------------------------------------------------------------------
+// CAknVolumeControl::DrawDefaultStyleVolumeControl()
+// NON SKINNED DRAW!
+// ----------------------------------------------------------------------------
+//
+void CAknVolumeControl::DrawDefaultStyleVolumeControl( const TRect& /*aRect*/ ) const
+ {
+ CWindowGc& gc=SystemGc();
+ MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+
+ //I'm not sure whether this branch is useless or not ,so I didn't delete this branch.
+ TInt volumeLIndex;
+ TAknLayoutRect layoutRect;
+
+ if ( AknStatuspaneUtils::IdleLayoutActive() )
+ {
+ volumeLIndex = 0;
+ }
+ else
+ {
+ volumeLIndex = 1;
+ }
+
+ TRect parent( TSize( 0, 0 ) );
+ TRect volumeNaviPaneRect; // volume_navi_pane
+
+ gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
+ gc.SetPenStyle(CGraphicsContext::ENullPen); // column drawing should have no outline
+ TRgb c1, c2;
+
+ if (iStyle == ENaviPaneVolumeControl)
+ {
+ layoutRect.LayoutRect( parent, AKN_LAYOUT_WINDOW_volume_navi_pane( volumeLIndex ) );
+ volumeNaviPaneRect = layoutRect.Rect();
+
+ layoutRect.LayoutRect( volumeNaviPaneRect, AKN_LAYOUT_TABLE_Volume_pane_elements__one_( 0, 0 ) );
+ c1 = layoutRect.Color();
+ layoutRect.LayoutRect( volumeNaviPaneRect, AKN_LAYOUT_TABLE_Volume_pane_elements__one_( 0, 1 ) );
+ c2 = layoutRect.Color();
+ }
+ else // Popup volume needs different colors
+ {
+ layoutRect.LayoutRect( Rect(), AKN_LAYOUT_TABLE_Volume_pane_elements__one_( 0, 0 ) );
+ c1 = layoutRect.Color();
+ layoutRect.LayoutRect( Rect(), AKN_LAYOUT_TABLE_Setting_volume_pane_elements_SUB_TABLE_0( 2, 0 ) );
+ c2 = layoutRect.Color();
+ }
+
+ for (TInt i=0; i < KVolumeLevels; i++) // there is ten bars
+ {
+ if ( i < ScaledValue())
+ {
+ gc.SetBrushColor(c1);
+ }
+ else
+ {
+ gc.SetBrushColor(c2);
+ }
+
+ if ( iStyle != ENaviPaneVolumeControl )
+ {
+ TRect tempRect( 0, 0, 0, 0 );
+ layoutRect.LayoutRect( tempRect, AKN_LAYOUT_TABLE_Volume_pane_elements__one_( i, 0 ) );
+ TPoint start( iStartPos.iX + layoutRect.Rect().iTl.iX, iStartPos.iY + layoutRect.Rect().iTl.iY );
+ TSize size( layoutRect.Rect().Size() );
+ gc.DrawRect( TRect( start, size ) );
+
+ if ( AknLayoutUtils::PenEnabled() )
+ {
+ // Store rect for every level. We can then decide what level was clicked
+ iExtension->iVolumeLevels[i] = layoutRect.Rect();
+ }
+ }
+ else
+ {
+ layoutRect.LayoutRect( volumeNaviPaneRect, AKN_LAYOUT_TABLE_Volume_pane_elements__one_( i, 0 ) );
+ gc.DrawRect( layoutRect.Rect() );
+
+ if ( AknLayoutUtils::PenEnabled() )
+ {
+ // Store rect for every level. We can then decide what level was clicked
+ iExtension->iVolumeLevels[i] = layoutRect.Rect();
+ }
+ }
+ }
+
+ }
+
+
+// ----------------------------------------------------------------------------
+// CAknVolumeControl::DrawSkinnedDefaultStyleVolumeControl()
+//
+// ----------------------------------------------------------------------------
+//
+void CAknVolumeControl::DrawSkinnedDefaultStyleVolumeControl(
+ const TRect& /*aRect*/ ) const
+ {
+ CWindowGc& gc=SystemGc();
+ // No test on AknsUtils::AvkonSkinEnabled() because this control is used in
+ // the navipane Skinned bitmap.
+ if ( !Background() )
+ {
+ MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+ AknsDrawUtils::Background( skin,
+ AknsDrawUtils::ControlContext( this ),
+ this,
+ gc,
+ Rect() );
+ }
+ else
+ {
+ Background()->Draw( gc, *this, Rect() );
+ }
+
+
+ // Draw speaker or mute icon
+ if ( ( iBitmap != NULL ) && ( iMaskBitmap != NULL ) )
+ {
+ TRect bmpRect(TPoint(0,0),TSize(iBitmap->SizeInPixels()));
+ if (iStyle == ENaviPaneVolumeControl) // popup handles icons itself
+ {
+ gc.BitBltMasked(iBmpPos, iBitmap, bmpRect, iMaskBitmap, ETrue);
+ }
+ }
+ if ( iExtension )
+ {
+ if ( ( iStyle != ENaviPaneVolumeControl ) ||
+ !( iExtension->iFlags & KVolumeNaviPaneMuted ) )
+ {
+ iExtension->DrawSvgSmallVolume( iStyle,
+ iExtension->iParentRect,
+ gc,
+ ScaledValue() );
+ return;
+ }
+ }
+
+ }
+
+
+// ----------------------------------------------------------------------------
+// CAknVolumeControl::ExtensionInterface()
+//
+// ----------------------------------------------------------------------------
+//
+EXPORT_C void* CAknVolumeControl::ExtensionInterface( TUid /*aInterface*/ )
+ {
+ return NULL;
+ }
+
+// ----------------------------------------------------------------------------
+// CAknVolumeControl::HandlePointerEventL()
+// Processes Volumecontrol's pointer event's.
+// This function requests what volume level contains the clicked point
+// And then set's new volumelevel according to that.
+// ----------------------------------------------------------------------------
+//
+EXPORT_C void CAknVolumeControl::HandlePointerEventL(
+ const TPointerEvent& aPointerEvent)
+ {
+ if ( AknLayoutUtils::PenEnabled() && iExtension )
+ {
+ if ( IsDimmed() )
+ {
+ iExtension->iFlags &= ~KVolumeButtonDown;
+ return;
+ }
+
+ TRect rect;
+ if ( iExtension->iUseExtendedTouchArea )
+ {
+ rect = iExtension->iTouchArea;
+ }
+ else
+ {
+ AknLayoutUtils::LayoutMetricsRect(
+ AknLayoutUtils::EApplicationWindow, rect );
+ }
+
+ TInt level = KVolumeLevelNotFound;
+ if( !rect.Contains( aPointerEvent.iPosition ) )
+ {
+ level = Value();
+ }
+ else
+ {
+ level = iExtension->GetVolumeLevelByPosition( iStyle,
+ aPointerEvent.iPosition, rect );
+ }
+
+ TBool valueChanged( EFalse ); // if pointerevent changes volume level
+
+ switch( aPointerEvent.iType )
+ {
+ case TPointerEvent::EButton1Down:
+ {
+ MTouchFeedback* feedback = MTouchFeedback::Instance();
+ if ( feedback )
+ {
+ feedback->InstantFeedback( ETouchFeedbackSlider );
+ }
+ }
+ case TPointerEvent::EDrag:
+ case TPointerEvent::EButtonRepeat: // fall trough
+ {
+ // click was inside VolumeControl
+ if ( rect.Contains( aPointerEvent.iPosition ) )
+ {
+ // Pointer down in volumeControl
+ iExtension->iFlags |= KVolumeButtonDown;
+ valueChanged = ETrue;
+ }
+ Window().RequestPointerRepeatEvent( KScrollRepeatTimeout, rect );
+ }
+ break;
+
+ case TPointerEvent::EButton1Up:
+ {
+ // if pointer was putted down inside VolumeControl
+ iExtension->iFlags &= ~KVolumeButtonDown;
+ }
+ break;
+
+ default:
+ break;
+ }
+ // get clicked volume level depending type of volumebar
+ if ( valueChanged )
+ {
+ if ( aPointerEvent.iType == TPointerEvent::EButton1Down )
+ {
+ iExtension->iReduce = ( level <= Value() );
+ iExtension->iOldLevel = level;
+ }
+ if ( level < Value() )
+ {
+ iExtension->iReduce = ETrue;
+ }
+ else if ( level > Value() + 1 )
+ {
+ iExtension->iReduce = ( level < iExtension->iOldLevel );
+ }
+ else if ( iExtension->iReduce &&
+ ( level == Value() || level == Value() + 1 ) )
+ {
+ level--;
+ }
+ }
+ //value step change
+ // correction should not be done when outside of control
+ if( iExtension->iFlags & KVolumeStepChange )
+ {
+ if( level > Value() )
+ {
+ level = Value() + 1;
+ }
+ else if( level < Value() )
+ {
+ level = Value() - 1;
+ }
+ }//value step change over
+ if ( level < iExtension->iMinimumValue )
+ {
+ level = iExtension->iMinimumValue;
+ }
+ else if ( level > iExtension->iMaximumValue )
+ {
+ level = iExtension->iMaximumValue;
+ }
+
+ iExtension->iOldLevel = level;
+
+ if ( level == KVolumeLevelMuteTapped )
+ {
+ if ( aPointerEvent.iType == TPointerEvent::EButton1Up )
+ {
+ // mute indicator was tapped
+ if ( Value() == iExtension->iMinimumValue )
+ {
+ // restore saved value
+ level = iExtension->iStoredLevel;
+ iExtension->iStoredLevel = iExtension->iMinimumValue;
+ }
+ else
+ {
+ // mute
+ iExtension->iStoredLevel = Value();
+ level = iExtension->iMinimumValue;
+ }
+ valueChanged = ETrue;
+ }
+ else
+ {
+ // ignore
+ return;
+ }
+ }
+
+ if ( valueChanged && (level != iValue) )
+ {
+ if ( aPointerEvent.iType == TPointerEvent::EDrag ||
+ aPointerEvent.iType == TPointerEvent::EButtonRepeat )
+ {
+ MTouchFeedback* feedback = MTouchFeedback::Instance();
+ if ( feedback )
+ {
+ feedback->InstantFeedback( this, ETouchFeedbackSlider );
+ }
+ }
+
+ iValue = level;
+ SetValue(iValue);
+ ReportEventL(MCoeControlObserver::EEventStateChanged);
+ DrawDeferred();
+ }
+ }
+ }
+
+
+// ----------------------------------------------------------------------------
+// CAknVolumeControl::HandleNaviDecoratorEventL()
+// Observes navigation decorator's events
+// currently possibly events are right and left arrow presses by pointer
+// increments/decrements volumelevel depending on event.
+// ----------------------------------------------------------------------------
+//
+EXPORT_C void CAknVolumeControl::HandleNaviDecoratorEventL( TInt aEventID )
+ {
+ if ( AknLayoutUtils::PenEnabled() )
+ {
+ switch(aEventID)
+ {
+ case MAknNaviDecoratorObserver::EAknNaviDecoratorEventLeftTabArrow:
+ {
+ if ( iExtension && iValue > iExtension->iMinimumValue )
+ {
+ iValue -= 1;
+ SetValue( iValue );
+ ReportEventL(MCoeControlObserver::EEventStateChanged);
+ DrawDeferred();
+ }
+ }
+ break;
+
+ case MAknNaviDecoratorObserver::EAknNaviDecoratorEventRightTabArrow:
+ if ( iExtension && iValue < iExtension->iMaximumValue )
+ {
+ iValue+=1;
+ SetValue(iValue);
+ ReportEventL(MCoeControlObserver::EEventStateChanged);
+ DrawDeferred();
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+
+// ----------------------------------------------------------------------------
+// CAknVolumeControl::IndicationDrawCallbackL()
+//
+// ----------------------------------------------------------------------------
+//
+TInt CAknVolumeControl::IndicationDrawCallbackL( TAny* aThis )
+ {
+ CAknVolumeControl* volumeControl =
+ static_cast<CAknVolumeControl*>(aThis);
+
+ volumeControl->SmallDirectionIndicationL();
+
+ return KErrNone;
+ }
+
+// ----------------------------------------------------------------------------
+// CAknVolumeControl::SmallDirectionIndicationL()
+//
+// ----------------------------------------------------------------------------
+//
+void CAknVolumeControl::SmallDirectionIndicationL()
+ {
+ // We must calculate redraw area either the biggest or the smallest
+ // volume bar
+
+ TRect rect;
+ TPoint p;
+ TRect srcRect;
+ TRect bmpRect;
+
+ // check the icon or bitmap is not null
+ TBool checkNull(EFalse);
+
+ // Cancel blinking if moved from min or max position, unless the area is
+ // blank. Then redraw and cancel after redraw
+ if( iExtension && iValue != iExtension->iAnimatedEffectValue &&
+ iExtension->iEffectTimerCount%2 == 0)
+ {
+ iExtension->iTimer->Cancel();
+ return;
+ }
+
+ // CDMA case
+ if( iExtension && iExtension->iAnimatedEffectValue == 0 )
+ {
+ iExtension->iAnimatedEffectValue += 1;
+ }
+
+ TInt scaledValue = ScaledValue(); // scale the value to make possible the dynamic range
+ if ( iExtension && iStyle == ESettingsVolumeControl )
+ {
+ rect = iExtension->RectFromLayout( iExtension->iParentRect,
+ AknLayoutScalable_Avkon::volume_set_pane_g(
+ scaledValue - 1 ));
+ if (AknsUtils::AvkonSkinEnabled() && iExtension)
+ {
+ p = TPoint( rect.iTl.iX, rect.iTl.iY );
+ srcRect = TRect(0, 0, rect.Width(), rect.Height());
+ }
+ }
+ else // navipane volume control, popup volume control
+ {
+ if ( iBitmap != NULL )
+ {
+ bmpRect = TRect(TPoint(0,0),TSize(iBitmap->SizeInPixels()));
+ }
+
+ if ( iExtension && AknStatuspaneUtils::SmallLayoutActive() )
+ {
+ rect = iExtension->RectFromLayout( iExtension->iParentRect,
+ AknLayoutScalable_Avkon::volume_small2_pane_g(
+ scaledValue - 1 ) );
+ }
+ else if( iExtension )
+ {
+ rect = iExtension->RectFromLayout( iExtension->iParentRect,
+ AknLayoutScalable_Avkon::volume_small_pane_g(
+ scaledValue - 1 ) );
+ }
+
+ p = TPoint( rect.iTl.iX, rect.iTl.iY );
+ srcRect = TRect(0, 0, rect.Width(), rect.Height());
+ }
+
+ Window().Invalidate(rect);
+ ActivateGc();
+
+ Window().BeginRedraw(rect);
+ CWindowGc& gc=SystemGc();
+ if( !Background() )
+ {
+ MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+
+ MAknsControlContext* edCc = AknsDrawUtils::ControlContext( this );
+ AknsDrawUtils::Background( skin, edCc, this, gc, rect);
+ }
+ else
+ {
+ Background()->Draw( gc, *this, rect );
+ }
+ if( iExtension && iExtension->iEffectTimerCount%2 == 1)
+ {
+ checkNull = ( iExtension->iActiveIcons[
+ scaledValue-1] != NULL )
+ && ( iExtension->iActiveMasks[
+ scaledValue-1] != NULL );
+ if (iStyle==ESettingsVolumeControl)
+ {
+ gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
+ gc.SetPenStyle(CGraphicsContext::ENullPen);
+ if ( AknsUtils::AvkonSkinEnabled() && iExtension
+ && checkNull )
+ {
+ gc.SetBrushStyle(CGraphicsContext::ENullBrush);
+ gc.BitBltMasked( p,
+ iExtension->iActiveIcons[
+ scaledValue-1],
+ srcRect,
+ iExtension->iActiveMasks[
+ scaledValue-1],
+ ETrue);
+ }
+ }
+ else
+ {
+ if ( iExtension && checkNull )
+ {
+ gc.BitBltMasked( p,
+ iExtension->iActiveIcons[
+ scaledValue-1],
+ srcRect,
+ iExtension->iActiveMasks[
+ scaledValue-1],
+ ETrue);
+ }
+ }
+ }
+ Window().EndRedraw();
+ DeactivateGc();
+ if( iExtension )
+ {
+ iExtension->iEffectTimerCount++;
+ }
+
+ // Stop timer if done normal-inverted-normal-inverted-normal sequence
+ // or the user has changed the value from the min or max
+ if( iExtension &&
+ ( iExtension->iEffectTimerCount > 3 || iExtension->iAnimatedEffectValue != iValue ) )
+ {
+ iExtension->iTimer->Cancel();
+ }
+
+ }
+
+// ----------------------------------------------------------------------------
+// CAknVolumeControl::StartTimerL()
+//
+// ----------------------------------------------------------------------------
+//
+void CAknVolumeControl::StartTimerL()
+ {
+ if(iExtension->iTimer->IsActive())
+ return; // do not re-start as we have the feedback ongoing
+
+ iExtension->iEffectTimerCount = 0;
+ iExtension->iAnimatedEffectValue = ScaledValue();
+
+ const TTimeIntervalMicroSeconds32 KVolumeFeedbackActionTime = 160*1000;
+
+ TCallBack callback(IndicationDrawCallbackL,this);
+ iExtension->iTimer->Start(KVolumeFeedbackActionTime,
+ KVolumeFeedbackActionTime, callback);
+ }
+
+
+// ----------------------------------------------------------------------------
+// CAknVolumeControl::CreateNaviIconL()
+// (Re)creates the navi pane icon.
+// ----------------------------------------------------------------------------
+//
+void CAknVolumeControl::CreateNaviIconL()
+ {
+ if ( !iExtension )
+ {
+ return;
+ }
+
+ TInt bmpId = iExtension->iBmpId;
+ TInt bmpMask = iExtension->iBmpMask;
+
+ // We compare to avkon.rh STRUCT VOLUME default values
+ if ( iExtension->iBmpFilename.CompareF(_L("")) != 0 )
+ {
+ MAknsSkinInstance *skin = AknsUtils::SkinInstance();
+ if ( iExtension->iFlags & KVolumeNaviPaneMuted )
+ {
+ delete iBitmap;
+ iBitmap = NULL;
+ delete iMaskBitmap;
+ iMaskBitmap = NULL;
+ AknsUtils::CreateColorIconL(skin,
+ KAknsIIDQgnIndiSpeakerMuted,
+ KAknsIIDQsnTextColors,
+ EAknsCIQsnTextColorsCG19,
+ iBitmap,
+ iMaskBitmap,
+ KAvkonBitmapFile,
+ EMbmAvkonQgn_indi_speaker_muted,
+ EMbmAvkonQgn_indi_speaker_muted_mask,
+ KRgbWhite );
+ }
+ else
+ {
+ if ( bmpId != -1 )
+ {
+ delete iBitmap;
+ iBitmap = NULL;
+ delete iMaskBitmap;
+ iMaskBitmap = NULL;
+
+ if ( bmpMask != -1 )
+ {
+ AknsUtils::CreateColorIconL( skin,
+ KAknsIIDQgnIndiSpeakerActive,
+ KAknsIIDQsnTextColors,
+ EAknsCIQsnTextColorsCG19,
+ iBitmap,
+ iMaskBitmap,
+ iExtension->iBmpFilename,
+ bmpId,
+ bmpMask,
+ KRgbWhite );
+ // sizes are set in setlayoutl
+ }
+ else
+ {
+ iBitmap = AknIconUtils::CreateIconL(
+ iExtension->iBmpFilename, bmpId );
+ }
+ }
+ }
+ }
+ }
+
+
+
+// ----------------------------------------------------------------------------
+// CAknVolumeControl::ScaledValue()
+//
+// ----------------------------------------------------------------------------
+//
+TInt CAknVolumeControl::ScaledValue() const
+ {
+ TInt scaledValue = iValue;
+ if(iExtension && !iExtension->iOldScaleSettingVolume)
+ {
+ scaledValue = 10 * ( iValue - iExtension->iMinimumValue )
+ / ( iExtension->iMaximumValue - iExtension->iMinimumValue );
+ }
+ return scaledValue;
+ }
+
+
+// ----------------------------------------------------------------------------
+// CAknVolumeControl::UseExtendedTouchArea
+//
+// ----------------------------------------------------------------------------
+//
+void CAknVolumeControl::UseExtendedTouchArea()
+ {
+ TRect touchActiveArea;
+ TPoint winPosition( Window().AbsPosition() );
+ TRect appRect;
+ AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EApplicationWindow,
+ appRect );
+ TAknLayoutRect mainpaneRect;
+ mainpaneRect.LayoutRect( appRect, AknLayoutScalable_Apps::main_pane(3) );
+ touchActiveArea = mainpaneRect.Rect();
+
+ touchActiveArea.Move( touchActiveArea.iTl.iX - winPosition.iX,
+ touchActiveArea.iTl.iY - winPosition.iY );
+ iExtension->iTouchArea = touchActiveArea;
+ iExtension->iUseExtendedTouchArea = ETrue;
+ }
+
+
+// ----------------------------------------------------------------------------
+// CVolumeExtension::
+//
+// ----------------------------------------------------------------------------
+//
+CVolumeExtension::CVolumeExtension():
+ iMinimumValue( KVolumeNaviPaneMutedValue ),
+ iMaximumValue( KVolumeMaxValue ),
+ iGfxMode( KGfxModeNotLoaded ),
+ iOldScaleSettingVolume(EFalse),
+ iGrabPoint( EFalse )
+ {
+ iFlags |= KVolumeStepChange;
+ }
+
+// ----------------------------------------------------------------------------
+// CAknVolumeControl::HandleResourceChange()
+// Handles a change to CAknVolumeControl's resources.
+// Currently it handles the change of Skins
+// ----------------------------------------------------------------------------
+//
+EXPORT_C void CAknVolumeControl::HandleResourceChange(TInt aType)
+ {
+ if ((aType==KAknsMessageSkinChange) || (aType == KEikColorResourceChange)
+ || (aType == KEikDynamicLayoutVariantSwitch))
+ {
+ SizeChanged();
+ if ( iExtension )
+ {
+ iExtension->iHasBeenDrawn = EFalse;
+ }
+ }
+ CCoeControl::HandleResourceChange( aType );
+ }
+
+void CAknVolumeControl::SuppressDrawing( TBool aSuppress )
+ {
+ if ( iExtension )
+ {
+ iExtension->iNoDraw = aSuppress;
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CVolumeExtension::~CVolumeExtension
+//
+// ----------------------------------------------------------------------------
+//
+CVolumeExtension::~CVolumeExtension()
+ {
+ DeleteBitmaps();
+ if(iTimer && iTimer->IsActive())
+ iTimer->Cancel();
+ delete iTimer;
+ }
+
+// ----------------------------------------------------------------------------
+// CVolumeExtension::UseSvgDrawing
+//
+// ----------------------------------------------------------------------------
+//
+TBool CVolumeExtension::UseSvgDrawing()
+ {
+ return ETrue;
+ }
+
+// ----------------------------------------------------------------------------
+// CVolumeExtension::DeleteBitmaps
+//
+// ----------------------------------------------------------------------------
+//
+void CVolumeExtension::DeleteBitmaps()
+ {
+ TInt i;
+
+ for( i = 0; i < KVolumeLevels; i++)
+ {
+ delete iActiveIcons[i];
+ iActiveIcons[i] = NULL;
+ delete iActiveMasks[i];
+ iActiveMasks[i] = NULL;
+ delete iInActiveIcons[i];
+ iInActiveIcons[i] = NULL;
+ delete iInActiveMasks[i];
+ iInActiveMasks[i] = NULL;
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CVolumeExtension::SetIconSizes
+//
+// ----------------------------------------------------------------------------
+//
+void CVolumeExtension::SetIconSizes( TInt aStyle, const TRect& aParent ) const
+ {
+ TSize s;
+
+ if( iGfxMode == KGfxModeOld )
+ {
+ for( TInt i = 0; i < KVolumeLevels; i++)
+ {
+ switch ( aStyle )
+ {
+ case ESettingsVolumeControl:
+ s = RectFromLayout( aParent,
+ AknLayoutScalable_Avkon::volume_set_pane_g(i) ).Size();
+ break;
+ case ENaviPaneVolumeControl:
+ {
+ TRect parentRect(aParent);
+ if ( AknStatuspaneUtils::SmallLayoutActive() )
+ {
+ parentRect = RectFromLayout(
+ parentRect,
+ AknLayoutScalable_Avkon::volume_small2_pane()
+ );
+ s = RectFromLayout(
+ parentRect,
+ AknLayoutScalable_Avkon::volume_small2_pane_g( i )
+ ).Size();
+ }
+ else
+ {
+ parentRect = RectFromLayout(
+ parentRect,
+ AknLayoutScalable_Avkon::volume_small_pane()
+ );
+ s = RectFromLayout(
+ parentRect,
+ AknLayoutScalable_Avkon::volume_small_pane_g(i)
+ ).Size();
+ }
+ }
+ break;
+ case EPopupVolumeControl:
+ s = RectFromLayout(
+ aParent,
+ AknLayoutScalable_Avkon::volume_small_pane_g( i )
+ ).Size();
+ break;
+ case EDynRangeSettingsVolumeControl:
+ case EDynRangeNaviPaneVolumeControl:
+ case EDynRangePopupVolumeControl:
+ s.iHeight = iParentRect.Height();
+ s.iWidth = iParentRect.Width();
+ break;
+ default:
+ // can not happen
+ break;
+ }
+ if ( iActiveIcons[i] != NULL )
+ {
+ AknIconUtils::SetSize( iActiveIcons[i],
+ s, EAspectRatioNotPreserved );
+ }
+ if ( iInActiveIcons[i] != NULL )
+ {
+ AknIconUtils::SetSize( iInActiveIcons[i],s,
+ EAspectRatioNotPreserved );
+ }
+ }
+ }
+ else
+ {
+ s.iHeight = iParentRect.Height();
+ s.iWidth = iParentRect.Width();
+
+ if ( iActiveIcons[0] != NULL )
+ {
+ AknIconUtils::SetSize( iActiveIcons[0], s,
+ EAspectRatioNotPreserved );
+ }
+ if ( iInActiveIcons[0] != NULL )
+ {
+ AknIconUtils::SetSize( iInActiveIcons[0], s,
+ EAspectRatioNotPreserved );
+ }
+
+ }
+
+ }
+
+// ----------------------------------------------------------------------------
+// CVolumeExtension::LoadBitmapsL
+//
+// Multiple fallback levels for loading bitmaps:
+// 1. Try loading new bitmaps using skin (icons will be scaled)
+// 2. Try loading old bitmaps using skin (either small or large icons)
+// 3. Load new bitmaps without skins (icons will be scaled)
+// ----------------------------------------------------------------------------
+//
+void CVolumeExtension::LoadBitmapsL( TInt aStyle, const TRect& aParent )
+ {
+ DeleteBitmaps();
+
+ MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+ TInt err = -1;// Init to any value but 0
+
+//TODO: Verify that new skins are available and loaded
+
+ // 1. Load new with skin
+ TRAP( err, TryLoadBitmapsSkinnedL( skin ) );
+ iGfxMode = KGfxModeNew;
+
+ // 2. Load old with skin
+ if( err )
+ {
+ switch( aStyle )
+ {
+ case ESettingsVolumeControl:
+ TRAP( err, TryLoadBitmapsDefaultLargeL( skin ) );
+ iGfxMode = KGfxModeOld;
+ break;
+ case ENaviPaneVolumeControl:
+ case EPopupVolumeControl:
+ TRAP( err, TryLoadBitmapsDefaultSmallL( skin ) );
+ iGfxMode = KGfxModeOld;
+ break;
+ }
+ }
+
+ // 3. Load new without skin
+ if( err )
+ {
+ iGfxMode = KGfxModeNotLoaded;
+ TRAP( err, TryLoadBitmapsNoSkinL() ); // Last chance - must succeed.
+ iGfxMode = KGfxModeNew;
+ }
+ // There absolutely are no whatsoever icons available -> abort!
+ User::LeaveIfError( err );
+
+ SetIconSizes( aStyle, aParent );
+ }
+
+
+// ----------------------------------------------------------------------------
+// CVolumeExtension::TryLoadBitmapsSkinnedL
+//
+// ----------------------------------------------------------------------------
+//
+void CVolumeExtension::TryLoadBitmapsSkinnedL( MAknsSkinInstance* aSkin )
+ {
+ AknsUtils::CreateIconL(
+ aSkin,
+ KAknsIIDQgnGrafVolumeSetOff,
+ iInActiveIcons[0],
+ iInActiveMasks[0],
+ KNullDesC, // Disables fallback
+ EMbmAvkonQgn_graf_volume_small_off,
+ EMbmAvkonQgn_graf_volume_small_off_mask ) ;
+
+ AknsUtils::CreateIconL(
+ aSkin,
+ KAknsIIDQgnGrafVolumeSetOn,
+ iActiveIcons[0],
+ iActiveMasks[0],
+ KNullDesC, // Disables fallback
+ EMbmAvkonQgn_graf_volume_small_on,
+ EMbmAvkonQgn_graf_volume_small_on_mask );
+ }
+
+
+// ----------------------------------------------------------------------------
+// CVolumeExtension::
+//
+// ----------------------------------------------------------------------------
+//
+void CVolumeExtension::TryLoadBitmapsDefaultSmallL( MAknsSkinInstance* aSkin )
+ {
+ const TAknsItemID iconOffSkinIDArray[] =
+ {
+ KAknsIIDQgnGrafVolumeSmall1Off,
+ KAknsIIDQgnGrafVolumeSmall2Off,
+ KAknsIIDQgnGrafVolumeSmall3Off,
+ KAknsIIDQgnGrafVolumeSmall4Off,
+ KAknsIIDQgnGrafVolumeSmall5Off,
+ KAknsIIDQgnGrafVolumeSmall6Off,
+ KAknsIIDQgnGrafVolumeSmall7Off,
+ KAknsIIDQgnGrafVolumeSmall8Off,
+ KAknsIIDQgnGrafVolumeSmall9Off,
+ KAknsIIDQgnGrafVolumeSmall10Off
+ };
+ const TAknsItemID iconOnSkinIDArray[] =
+ {
+ KAknsIIDQgnGrafVolumeSmall1On,
+ KAknsIIDQgnGrafVolumeSmall2On,
+ KAknsIIDQgnGrafVolumeSmall3On,
+ KAknsIIDQgnGrafVolumeSmall4On,
+ KAknsIIDQgnGrafVolumeSmall5On,
+ KAknsIIDQgnGrafVolumeSmall6On,
+ KAknsIIDQgnGrafVolumeSmall7On,
+ KAknsIIDQgnGrafVolumeSmall8On,
+ KAknsIIDQgnGrafVolumeSmall9On,
+ KAknsIIDQgnGrafVolumeSmall10On
+ };
+ const TInt iconOffIDArray[] =
+ {
+ EMbmAvkonQgn_graf_volume_small_1_off,
+ EMbmAvkonQgn_graf_volume_small_2_off,
+ EMbmAvkonQgn_graf_volume_small_3_off,
+ EMbmAvkonQgn_graf_volume_small_4_off,
+ EMbmAvkonQgn_graf_volume_small_5_off,
+ EMbmAvkonQgn_graf_volume_small_6_off,
+ EMbmAvkonQgn_graf_volume_small_7_off,
+ EMbmAvkonQgn_graf_volume_small_8_off,
+ EMbmAvkonQgn_graf_volume_small_9_off,
+ EMbmAvkonQgn_graf_volume_small_10_off
+ };
+ const TInt iconOffMaskIDArray[] =
+ {
+ EMbmAvkonQgn_graf_volume_small_1_off_mask,
+ EMbmAvkonQgn_graf_volume_small_2_off_mask,
+ EMbmAvkonQgn_graf_volume_small_3_off_mask,
+ EMbmAvkonQgn_graf_volume_small_4_off_mask,
+ EMbmAvkonQgn_graf_volume_small_5_off_mask,
+ EMbmAvkonQgn_graf_volume_small_6_off_mask,
+ EMbmAvkonQgn_graf_volume_small_7_off_mask,
+ EMbmAvkonQgn_graf_volume_small_8_off_mask,
+ EMbmAvkonQgn_graf_volume_small_9_off_mask,
+ EMbmAvkonQgn_graf_volume_small_10_off_mask
+ };
+ const TInt iconOnIDArray[] =
+ {
+ EMbmAvkonQgn_graf_volume_small_1_on,
+ EMbmAvkonQgn_graf_volume_small_2_on,
+ EMbmAvkonQgn_graf_volume_small_3_on,
+ EMbmAvkonQgn_graf_volume_small_4_on,
+ EMbmAvkonQgn_graf_volume_small_5_on,
+ EMbmAvkonQgn_graf_volume_small_6_on,
+ EMbmAvkonQgn_graf_volume_small_7_on,
+ EMbmAvkonQgn_graf_volume_small_8_on,
+ EMbmAvkonQgn_graf_volume_small_9_on,
+ EMbmAvkonQgn_graf_volume_small_10_on
+ };
+ const TInt iconOnMaskIDArray[] =
+ {
+ EMbmAvkonQgn_graf_volume_small_1_on_mask,
+ EMbmAvkonQgn_graf_volume_small_2_on_mask,
+ EMbmAvkonQgn_graf_volume_small_3_on_mask,
+ EMbmAvkonQgn_graf_volume_small_4_on_mask,
+ EMbmAvkonQgn_graf_volume_small_5_on_mask,
+ EMbmAvkonQgn_graf_volume_small_6_on_mask,
+ EMbmAvkonQgn_graf_volume_small_7_on_mask,
+ EMbmAvkonQgn_graf_volume_small_8_on_mask,
+ EMbmAvkonQgn_graf_volume_small_9_on_mask,
+ EMbmAvkonQgn_graf_volume_small_10_on_mask
+ };
+
+ for ( TInt i=0; i<10; i++ )
+ {
+ AknsUtils::CreateIconL(
+ aSkin,
+ iconOffSkinIDArray[i],
+ iInActiveIcons[i],
+ iInActiveMasks[i],
+ KNullDesC,
+ iconOffIDArray[i],
+ iconOffMaskIDArray[i]
+ );
+ AknsUtils::CreateIconL(
+ aSkin,
+ iconOnSkinIDArray[i],
+ iActiveIcons[i],
+ iActiveMasks[i],
+ KNullDesC,
+ iconOnIDArray[i],
+ iconOnMaskIDArray[i]
+ );
+ }
+ }
+
+
+// ----------------------------------------------------------------------------
+// CVolumeExtension::
+//
+// ----------------------------------------------------------------------------
+//
+void CVolumeExtension::TryLoadBitmapsDefaultLargeL( MAknsSkinInstance* aSkin )
+ {
+ const TAknsItemID iconOffSkinIDArray[] =
+ {
+ KAknsIIDQgnGrafVolumeSet1Off,
+ KAknsIIDQgnGrafVolumeSet2Off,
+ KAknsIIDQgnGrafVolumeSet3Off,
+ KAknsIIDQgnGrafVolumeSet4Off,
+ KAknsIIDQgnGrafVolumeSet5Off,
+ KAknsIIDQgnGrafVolumeSet6Off,
+ KAknsIIDQgnGrafVolumeSet7Off,
+ KAknsIIDQgnGrafVolumeSet8Off,
+ KAknsIIDQgnGrafVolumeSet9Off,
+ KAknsIIDQgnGrafVolumeSet10Off
+ };
+ const TAknsItemID iconOnSkinIDArray[] =
+ {
+ KAknsIIDQgnGrafVolumeSet1On,
+ KAknsIIDQgnGrafVolumeSet2On,
+ KAknsIIDQgnGrafVolumeSet3On,
+ KAknsIIDQgnGrafVolumeSet4On,
+ KAknsIIDQgnGrafVolumeSet5On,
+ KAknsIIDQgnGrafVolumeSet6On,
+ KAknsIIDQgnGrafVolumeSet7On,
+ KAknsIIDQgnGrafVolumeSet8On,
+ KAknsIIDQgnGrafVolumeSet9On,
+ KAknsIIDQgnGrafVolumeSet10On
+ };
+ const TInt iconOffIDArray[] =
+ {
+ EMbmAvkonQgn_graf_volume_set_1_off,
+ EMbmAvkonQgn_graf_volume_set_2_off,
+ EMbmAvkonQgn_graf_volume_set_3_off,
+ EMbmAvkonQgn_graf_volume_set_4_off,
+ EMbmAvkonQgn_graf_volume_set_5_off,
+ EMbmAvkonQgn_graf_volume_set_6_off,
+ EMbmAvkonQgn_graf_volume_set_7_off,
+ EMbmAvkonQgn_graf_volume_set_8_off,
+ EMbmAvkonQgn_graf_volume_set_9_off,
+ EMbmAvkonQgn_graf_volume_set_10_off
+ };
+ const TInt iconOffMaskIDArray[] =
+ {
+ EMbmAvkonQgn_graf_volume_set_1_off_mask,
+ EMbmAvkonQgn_graf_volume_set_2_off_mask,
+ EMbmAvkonQgn_graf_volume_set_3_off_mask,
+ EMbmAvkonQgn_graf_volume_set_4_off_mask,
+ EMbmAvkonQgn_graf_volume_set_5_off_mask,
+ EMbmAvkonQgn_graf_volume_set_6_off_mask,
+ EMbmAvkonQgn_graf_volume_set_7_off_mask,
+ EMbmAvkonQgn_graf_volume_set_8_off_mask,
+ EMbmAvkonQgn_graf_volume_set_9_off_mask,
+ EMbmAvkonQgn_graf_volume_set_10_off_mask
+ };
+ const TInt iconOnIDArray[] =
+ {
+ EMbmAvkonQgn_graf_volume_set_1_on,
+ EMbmAvkonQgn_graf_volume_set_2_on,
+ EMbmAvkonQgn_graf_volume_set_3_on,
+ EMbmAvkonQgn_graf_volume_set_4_on,
+ EMbmAvkonQgn_graf_volume_set_5_on,
+ EMbmAvkonQgn_graf_volume_set_6_on,
+ EMbmAvkonQgn_graf_volume_set_7_on,
+ EMbmAvkonQgn_graf_volume_set_8_on,
+ EMbmAvkonQgn_graf_volume_set_9_on,
+ EMbmAvkonQgn_graf_volume_set_10_on
+ };
+ const TInt iconOnMaskIDArray[] =
+ {
+ EMbmAvkonQgn_graf_volume_set_1_on_mask,
+ EMbmAvkonQgn_graf_volume_set_2_on_mask,
+ EMbmAvkonQgn_graf_volume_set_3_on_mask,
+ EMbmAvkonQgn_graf_volume_set_4_on_mask,
+ EMbmAvkonQgn_graf_volume_set_5_on_mask,
+ EMbmAvkonQgn_graf_volume_set_6_on_mask,
+ EMbmAvkonQgn_graf_volume_set_7_on_mask,
+ EMbmAvkonQgn_graf_volume_set_8_on_mask,
+ EMbmAvkonQgn_graf_volume_set_9_on_mask,
+ EMbmAvkonQgn_graf_volume_set_10_on_mask
+ };
+
+ for ( TInt i=0; i<10; i++ )
+ {
+ AknsUtils::CreateIconL(
+ aSkin,
+ iconOffSkinIDArray[i],
+ iInActiveIcons[i],
+ iInActiveMasks[i],
+ KNullDesC,
+ iconOffIDArray[i],
+ iconOffMaskIDArray[i]
+ );
+ AknsUtils::CreateIconL(
+ aSkin,
+ iconOnSkinIDArray[i],
+ iActiveIcons[i],
+ iActiveMasks[i],
+ KNullDesC,
+ iconOnIDArray[i],
+ iconOnMaskIDArray[i]
+ );
+ }
+
+ }
+
+
+// ----------------------------------------------------------------------------
+// CVolumeExtension::TryLoadBitmapsNoSkinL
+//
+// ----------------------------------------------------------------------------
+//
+void CVolumeExtension::TryLoadBitmapsNoSkinL()
+ {
+ AknIconUtils::CreateIconL(
+ iInActiveIcons[0],
+ iInActiveMasks[0],
+ KAvkonBitmapFile,
+ EMbmAvkonQgn_graf_volume_small_off,
+ EMbmAvkonQgn_graf_volume_small_off_mask );
+ AknIconUtils::CreateIconL(
+ iActiveIcons[0],
+ iActiveMasks[0],
+ KAvkonBitmapFile,
+ EMbmAvkonQgn_graf_volume_small_on,
+ EMbmAvkonQgn_graf_volume_small_on_mask );
+ }
+
+// ----------------------------------------------------------------------------
+// CVolumeExtension::CalculateParentRect
+//
+// ----------------------------------------------------------------------------
+//
+void CVolumeExtension::CalculateParentRect( TInt aStyle, const TRect& aParent )
+ {
+ switch (aStyle)
+ {
+ case ENaviPaneVolumeControl:
+ case EDynRangeNaviPaneVolumeControl:
+ {
+ // Rect() gives navi_navi_volume_pane in the control hierarchy.
+ if ( AknStatuspaneUtils::SmallLayoutActive() )
+ {
+ iParentRect = RectFromLayout(
+ aParent,
+ AknLayoutScalable_Avkon::volume_small2_pane()
+ );
+ }
+ else
+ {
+ iParentRect = RectFromLayout(
+ aParent,
+ AknLayoutScalable_Avkon::volume_small_pane()
+ );
+ }
+ }
+ break;
+ case ESettingsVolumeControl:
+ case EPopupVolumeControl:
+ default:
+ iParentRect = aParent; // Rect()
+ break;
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CVolumeExtension::DrawSvgSmallVolume
+//
+// ----------------------------------------------------------------------------
+//
+void CVolumeExtension::DrawSvgSmallVolume(
+ TInt aStyle,
+ const TRect& aRect,
+ CBitmapContext& aGc,
+ TInt aValue
+ )
+ {
+ TRect r;
+ for (TInt i = 0; i < KVolumeLevels; i++)
+ {
+ if ( aStyle == EPopupVolumeControl )
+ {
+ r = RectFromLayout( aRect,
+ AknLayoutScalable_Avkon::volume_small_pane_g( i ) );
+ }
+ else // navi pane volume control
+ {
+ if ( AknStatuspaneUtils::SmallLayoutActive() )
+ {
+ r = RectFromLayout( aRect,
+ AknLayoutScalable_Avkon::volume_small2_pane_g( i ) );
+ }
+ else
+ {
+ r = RectFromLayout( aRect,
+ AknLayoutScalable_Avkon::volume_small_pane_g( i ) );
+ }
+ }
+
+ TPoint p( r.iTl.iX, r.iTl.iY );
+ TRect srcRect(0, 0, r.Width(), r.Height());
+
+ if ( AknLayoutUtils::PenEnabled() )
+ {
+ // Store rect for every level.
+ // We can then decide what level was clicked
+ iVolumeLevels[i] = r;
+ }
+
+ if ( i < aValue )
+ {
+ if ( ( iActiveIcons[i] != NULL ) && ( iActiveMasks[i] != NULL ) )
+ {
+ aGc.BitBltMasked( p, iActiveIcons[i],
+ srcRect, iActiveMasks[i], ETrue);
+ }
+ }
+ else
+ {
+ if ( ( iInActiveIcons[i] != NULL )
+ && ( iInActiveMasks[i] != NULL ) )
+ {
+ aGc.BitBltMasked( p, iInActiveIcons[i],
+ srcRect, iInActiveMasks[i], ETrue);
+ }
+ }
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CVolumeExtension::DrawSvgSettingsVolume
+//
+// ----------------------------------------------------------------------------
+//
+void CVolumeExtension::DrawSvgSettingsVolume( const TRect& aRect,
+ CWindowGc& aGc, TInt aValue )
+ {
+ TRect r;
+ for (TInt i = 0; i < KVolumeLevels; i++)
+ {
+ r = RectFromLayout( aRect,
+ AknLayoutScalable_Avkon::volume_set_pane_g( i ) );
+ TPoint p( r.iTl.iX, r.iTl.iY );
+ TRect srcRect(0, 0, r.Width(), r.Height());
+
+ if ( AknLayoutUtils::PenEnabled() )
+ {
+ // Store rect for every level.
+ // We can then decide what level was clicked
+ iVolumeLevels[i] = r;
+ }
+
+ if ( i < aValue )
+ {
+ if ( ( iActiveIcons[i] != NULL ) && ( iActiveMasks[i] != NULL ) )
+ {
+ aGc.BitBltMasked( p, iActiveIcons[i],
+ srcRect, iActiveMasks[i], ETrue);
+ }
+ }
+ else
+ {
+ if ( ( iInActiveIcons[i] != NULL )
+ && ( iInActiveMasks[i] != NULL ) )
+ {
+ aGc.BitBltMasked( p, iInActiveIcons[i], srcRect,
+ iInActiveMasks[i], ETrue);
+ }
+ }
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CVolumeExtension::
+//
+// ----------------------------------------------------------------------------
+//
+void CVolumeExtension::CreateSvgSettingsIconL(
+ const TRect& aRect, TInt aValue, CGulIcon* aIcon )
+ {
+ CVolumeExtension* extension = new (ELeave) CVolumeExtension;
+ CleanupStack::PushL( extension );
+
+ extension->LoadBitmapsL( ENaviPaneVolumeControl, aRect );
+ extension->DrawSvgSettingsIconL( aRect, aValue, aIcon );
+
+ CleanupStack::PopAndDestroy(); // extension
+ }
+// ----------------------------------------------------------------------------
+// CVolumeExtension::
+//
+// ----------------------------------------------------------------------------
+//
+void CVolumeExtension::CreateDynRangeStyleSettingsIconL( const TRect& aRect,
+ TInt aValue,
+ CGulIcon* aIcon,
+ TInt aMinimum,
+ TInt aMaximum )
+ {
+ CVolumeExtension* extension = new (ELeave) CVolumeExtension;
+ CleanupStack::PushL( extension );
+
+ extension->LoadBitmapsL( EDynRangeSettingsVolumeControl, aRect );
+ extension->DrawDynRangeStyleSettingsIconL( aRect, aValue, aIcon, aMinimum, aMaximum );
+
+ CleanupStack::PopAndDestroy(); // extension
+ }
+// ----------------------------------------------------------------------------
+// CVolumeExtension::
+//
+// ----------------------------------------------------------------------------
+//
+void CVolumeExtension::DrawSvgSettingsIconL(
+ const TRect& aRect, TInt aValue, CGulIcon* aIcon )
+ {
+ __ASSERT_DEBUG( ( aValue >= iMinimumValue )
+ && (aValue <= iMaximumValue),
+ Panic(EAknPanicOutOfRange) );
+ if( iGfxMode == KGfxModeNew )
+ {
+ DrawDynRangeStyleSettingsIconL( aRect, aValue, aIcon, iMinimumValue, iMaximumValue );
+ }
+ else
+ {
+
+ // The actual bitmap
+ CFbsBitmap* bitmap = new (ELeave) CFbsBitmap;
+ CleanupStack::PushL( bitmap );
+
+ bitmap->Create( aRect.Size(),
+ CCoeEnv::Static()->ScreenDevice()->DisplayMode() );
+ CFbsBitGc* fbsBitGc = CFbsBitGc::NewL();
+ CleanupStack::PushL( fbsBitGc );
+ CFbsBitmapDevice* bmpDevice = CFbsBitmapDevice::NewL( bitmap );
+ CleanupStack::PushL( bmpDevice );
+ fbsBitGc->Activate( bmpDevice );
+
+ TRect r;
+
+ for (TInt i = 0; i < KVolumeLevels; i++)
+ {
+ r = RectFromLayout( aRect,
+ AknLayoutScalable_Avkon::volume_small_pane_cp_g(i));
+ TPoint p( r.iTl.iX, r.iTl.iY );
+ TRect srcRect(0, 0, r.Width(), r.Height());
+
+ if ( AknLayoutUtils::PenEnabled() )
+ {
+ // Store rect for every level.
+ // We can then decide what level was clicked
+ iVolumeLevels[i] = r;
+ }
+
+ if ( i < aValue )
+ {
+ if ( iActiveIcons[i] != NULL )
+ {
+ AknIconUtils::SetSize( iActiveIcons[i], r.Size() );
+ fbsBitGc->BitBlt( p, iActiveIcons[i], srcRect );
+ }
+ }
+ else
+ {
+ if ( iInActiveIcons[i] != NULL )
+ {
+ AknIconUtils::SetSize( iInActiveIcons[i], r.Size() );
+ fbsBitGc->BitBlt( p, iInActiveIcons[i], srcRect );
+ }
+ }
+ }
+
+ CleanupStack::PopAndDestroy( 2 ); // bmpDevice, fbsBitGc
+ aIcon->SetBitmap( bitmap ); // Transfers ownership
+ CleanupStack::Pop(); // bitmap
+
+ // The mask
+ CFbsBitmap* mask = new (ELeave) CFbsBitmap;
+ CleanupStack::PushL( mask );
+
+ mask->Create( aRect.Size(), iActiveMasks[0]->DisplayMode() );
+ fbsBitGc = CFbsBitGc::NewL();
+ CleanupStack::PushL( fbsBitGc );
+ bmpDevice = CFbsBitmapDevice::NewL( mask );
+ CleanupStack::PushL( bmpDevice );
+ fbsBitGc->Activate( bmpDevice );
+ fbsBitGc->SetPenStyle( CGraphicsContext::ENullPen );
+ fbsBitGc->SetBrushStyle( CGraphicsContext::ESolidBrush );
+ fbsBitGc->SetBrushColor( KRgbBlack );
+ fbsBitGc->DrawRect( TRect( aRect.Size() ) );
+
+ fbsBitGc->SetBrushStyle( CGraphicsContext::ENullBrush );
+
+ for ( TInt i = 0; i < KVolumeLevels; i++ )
+ {
+ r = RectFromLayout( aRect,
+ AknLayoutScalable_Avkon::volume_small_pane_cp_g( i ) );
+ TPoint p( r.iTl.iX, r.iTl.iY );
+ TRect srcRect( 0, 0, r.Width(), r.Height() );
+
+ if ( i < aValue )
+ {
+ if ( ( iActiveMasks[i] != NULL ) )
+ {
+ AknIconUtils::SetSize( iActiveMasks[i], r.Size() );
+ fbsBitGc->BitBlt( p, iActiveMasks[i], srcRect );
+ }
+ }
+ else
+ {
+ if ( iInActiveMasks[i] != NULL )
+ {
+ AknIconUtils::SetSize( iInActiveMasks[i], r.Size() );
+ fbsBitGc->BitBlt( p, iInActiveMasks[i], srcRect );
+ }
+ }
+ }
+
+ CleanupStack::PopAndDestroy( 2 ); // bmpDevice, fbsBitGc
+ aIcon->SetMask( mask ); // Transfers ownership
+ CleanupStack::Pop(); // mask
+ }
+ }
+// ----------------------------------------------------------------------------
+// CVolumeExtension::
+//
+// ----------------------------------------------------------------------------
+//
+void CVolumeExtension::DrawDynRangeStyleSettingsIconL( const TRect& aRect,
+ TInt aValue,
+ CGulIcon* aIcon,
+ TInt aMinimum,
+ TInt aMaximum )
+ {
+ __ASSERT_DEBUG( ( aValue >= aMinimum )
+ && (aValue <= aMaximum),
+ Panic(EAknPanicOutOfRange) );
+
+ // The actual bitmap
+ CFbsBitmap* bitmap = new (ELeave) CFbsBitmap;
+ CleanupStack::PushL( bitmap );
+
+ bitmap->Create( aRect.Size(),
+ CCoeEnv::Static()->ScreenDevice()->DisplayMode() );
+ CFbsBitGc* fbsBitGc = CFbsBitGc::NewL();
+ CleanupStack::PushL( fbsBitGc );
+ CFbsBitmapDevice* bmpDevice = CFbsBitmapDevice::NewL( bitmap );
+ CleanupStack::PushL( bmpDevice );
+ fbsBitGc->Activate( bmpDevice );
+
+ TRect r( aRect );
+ // the following is original code
+ // TRect activeRect(r.iTl.iX, r.iTl.iY, r.Width() * aValue/( aMaximum - aMinimum + 1 ), r.Height());
+ // but the following is changed
+ // just remove +1 from denominator, because it should be aMaximum - aMinimum
+ // and caculate the activeRect seperately according to the iOld ScaleSettingVolume.
+ TInt range;
+ if( iOldScaleSettingVolume )
+ {
+ range = KVolumeLevels ;
+ }
+ else
+ {
+ range = aMaximum - aMinimum ;
+ }
+ TRect activeRect(r.iTl.iX, r.iTl.iY, r.Width() * aValue/range, r.Height());
+ TRect inActiveRect( activeRect.iBr.iX, activeRect.iTl.iY, r.iBr.iX, r.iBr.iY );
+
+ if ( iActiveIcons[0] != NULL && iInActiveIcons[0] != NULL )
+ {
+ // add the last parameter for every SetSize() function
+ // In order to make the solid graphic has the same size as the volume control
+ AknIconUtils::SetSize( iActiveIcons[0], r.Size(),EAspectRatioNotPreserved );
+ fbsBitGc->BitBlt( activeRect.iTl, iActiveIcons[0], activeRect );
+ AknIconUtils::SetSize( iInActiveIcons[0], r.Size(),EAspectRatioNotPreserved );
+ fbsBitGc->BitBlt( inActiveRect.iTl, iInActiveIcons[0], inActiveRect );
+
+ }
+
+ CleanupStack::PopAndDestroy( 2 ); // bmpDevice, fbsBitGc
+ aIcon->SetBitmap( bitmap ); // Transfers ownership
+ CleanupStack::Pop(); // bitmap
+
+ // The mask
+ CFbsBitmap* mask = new (ELeave) CFbsBitmap;
+ CleanupStack::PushL( mask );
+
+ mask->Create( aRect.Size(), iActiveMasks[0]->DisplayMode() );
+ fbsBitGc = CFbsBitGc::NewL();
+ CleanupStack::PushL( fbsBitGc );
+ bmpDevice = CFbsBitmapDevice::NewL( mask );
+ CleanupStack::PushL( bmpDevice );
+ fbsBitGc->Activate( bmpDevice );
+ fbsBitGc->SetPenStyle( CGraphicsContext::ENullPen );
+ fbsBitGc->SetBrushStyle( CGraphicsContext::ESolidBrush );
+ fbsBitGc->SetBrushColor( KRgbBlack );
+ fbsBitGc->DrawRect( TRect( aRect.Size() ) );
+
+ fbsBitGc->SetBrushStyle( CGraphicsContext::ENullBrush );
+
+ if ( iActiveMasks[0] != NULL && iInActiveMasks[0] != NULL )
+ {
+ // add the last parameter for every SetSize() function
+ // In order to make the solid graphic has the same size as the volume control
+ AknIconUtils::SetSize( iActiveMasks[0], r.Size(),EAspectRatioNotPreserved );
+ fbsBitGc->BitBlt( activeRect.iTl, iActiveMasks[0], activeRect );
+ AknIconUtils::SetSize( iInActiveMasks[0], r.Size(),EAspectRatioNotPreserved );
+ fbsBitGc->BitBlt( inActiveRect.iTl, iInActiveMasks[0], inActiveRect );
+ }
+
+ CleanupStack::PopAndDestroy( 2 ); // bmpDevice, fbsBitGc
+ aIcon->SetMask( mask ); // Transfers ownership
+ CleanupStack::Pop(); // mask
+ }
+
+// ----------------------------------------------------------------------------
+// CVolumeExtension::RectFromLayout
+//
+// ----------------------------------------------------------------------------
+//
+TRect CVolumeExtension::RectFromLayout(const TRect& aParent,
+ const TAknWindowComponentLayout& aComponentLayout) const
+ {
+ TAknWindowLineLayout lineLayout = aComponentLayout.LayoutLine();
+ TAknLayoutRect layoutRect;
+ layoutRect.LayoutRect(aParent,lineLayout);
+ return layoutRect.Rect();
+ }
+
+// ----------------------------------------------------------------------------
+// CVolumeExtension::GetVolumeLevelByPosition()
+// This function Searches which iVolumeLevels array's element (TRect) contains
+// aPoint. The array is ordered so that the index can then be used to return
+// correct volume level. aAreaRect is used to add volumelevel's height to cover
+// whole area so user does not need to click "inside" level. This function also
+// calculates gap between volumelevel rects and returns correct volumelevel
+// also from clicks to these gaps
+// ----------------------------------------------------------------------------
+//
+TInt CVolumeExtension::GetVolumeLevelByPosition( const TInt& ,
+ const TPoint& aPoint,
+ const TRect& aAreaRect ) const
+ {
+ if ( AknLayoutUtils::PenEnabled() )
+ {
+ TInt volumeLevel = KVolumeLevelNotFound;
+ TInt range = iMaximumValue - iMinimumValue ;
+ // Use hi-res volume control with dynamic volume range
+ if( iGfxMode == KGfxModeNew )
+ {
+ // Check the point's position in iParentRect x-axis. Use this to
+ // define a value between iMinimumValue and iMaximumValue. Step
+ // size is always 1 (value is rounded up).
+ TInt pointInVolumeAxis = aPoint.iX - iParentRect.iTl.iX;
+ // This rouds up to integer.
+ TInt total( pointInVolumeAxis * range );
+ TInt volumePosition = total / iParentRect.Width() + iMinimumValue;
+ if ( total % iParentRect.Width() > 0 )
+ {
+ volumePosition++;
+ }
+
+ if( volumePosition >= iMinimumValue && volumePosition <= iMaximumValue )
+ {
+ volumeLevel = volumePosition;
+ }
+ else if(volumePosition > iMaximumValue)
+ {
+ volumeLevel = iMaximumValue;
+ }
+ else
+ {
+ volumeLevel = iMinimumValue;
+ }
+ }
+ // Use old volume implementation with range [0,10]
+ else
+ {
+ TRect nextRect;
+ TRect thisRect = iVolumeLevels[0];
+
+ if ( iMuteRect.Contains( aPoint ))
+ {
+ return KVolumeLevelMuteTapped;
+ }
+
+ for (TInt i = 1; i <= KVolumeLevels; i++)
+ {
+ // do not read next rect, if this is last round
+ if ( i < KVolumeLevels )
+ {
+ // read rect for volume level i
+ nextRect = iVolumeLevels[i];
+
+ // set thisRect to contain half of gap between this and next
+ // rect
+ // + 1 because right and bottom borders are not "inside" rect
+ thisRect.iBr.iX = (nextRect.iTl.iX - thisRect.iBr.iX)/2
+ + thisRect.iBr.iX;
+
+ // set nextRect to contain other half of gap
+ // between these two rects
+ nextRect.iTl.iX = thisRect.iBr.iX;
+ }
+
+ // set volumebars where pointer is accepted
+ // for it to be as high as area.
+ thisRect.iTl.iY = aAreaRect.iTl.iY;
+ thisRect.iBr.iY = aAreaRect.iBr.iY;
+
+ if ( thisRect.Contains( aPoint ))
+ {
+ // Because array is zero indexed, but volumes starts at 1
+ //--> Conversion by adding one before return.
+ // (and here so that it needs to be done only once)
+ volumeLevel = i;
+ volumeLevel = volumeLevel * range/KVolumeLevels;
+ break;
+ }
+ thisRect = nextRect;
+ }
+ if( aPoint.iX > iVolumeLevels[KVolumeLevels-1].iBr.iX )
+ {
+ volumeLevel = iMaximumValue;
+ }
+ else if( aPoint.iX < iVolumeLevels[0].iBr.iX )
+ {
+ volumeLevel = iMinimumValue;
+ }
+ }
+ return volumeLevel;
+ }
+ else
+ {
+ // Should not occur, just prevent complier's warning
+ return 0;
+ }
+ }
+
+// End of File