diff -r 000000000000 -r 2f259fa3e83a uifw/AvKon/src/Aknslider.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uifw/AvKon/src/Aknslider.cpp Tue Feb 02 01:00:49 2010 +0200 @@ -0,0 +1,4339 @@ +/* +* 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: +* +*/ + + +// INCLUDE FILES +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "aknslider.h" + +#include + +// Large enough for a 20 digit number or fraction with two 9 digit numbers. +// This number is not in the header as it does not need to be known by the +// client. +const TInt KAknSliderValueLabelValueMaxLength = 20; + +// This value is used to account for the safety demands of StringLoader. It +// requires extra length in the target descriptor of its formatting than you +// would expect. +const TInt KAknSliderFormatKeyLength = 2; + +// This value is the optimum number of repeat key events to get through the +// range of the slider. + +const TInt KAknSliderFeedbackActionTime = 160 * 1000; // Interval, microseconds + +// Default draw color +const TInt KAknSliderDefaultDrawColor = 120; +const TInt KScrollRepeatTimeout = 250000; // 0.25 seconds +const TInt KStableFeedbackIntesity = 50; +const TInt KFeedbackTimeout = 100000; +const TInt KNoFeedbackTimeout = 0; +const TInt KStepThreshold = 15; +// ============================================================================ +// Internal class to hold slider control data, primarily coming from resource. +NONSHARABLE_CLASS( CAknSliderData ): public CBase + { +public: + static CAknSliderData* NewLC( TInt aResourceId ); + static CAknSliderData* NewL( TResourceReader& aReader ); + ~CAknSliderData(); + + void SetRange( TInt aMinimumValue, TInt aMaximumValue ); + inline TInt Range() const + { + return iMaximumValue - iMinimumValue; + } + + void SetDecimalPlaces( TInt aDecimalPlaces ); + inline TInt DecimalPlaces() const + { + return iDecimalPlaces; + } + + +private: + CAknSliderData(); + void ConstructFromResourceL( TInt aResourceId ); + void ConstructFromResourceL( TResourceReader& aReader ); + + // Copy constructor, declared not defined -> disabled + CAknSliderData( const CAknSliderData& aData ); + // Assignment operator, declared not defined -> disabled + const CAknSliderData& operator=( const CAknSliderData& aData ); + +public: + TInt iMinimumValue; + TInt iMaximumValue; + TInt iStepSize; + TInt iValueType; + TInt iLayout; + HBufC* iText; // Owned + + // Text to be used for the singular label if needed. Owned + HBufC* iSingularText; + + HBufC* iMinimumLabelText; // Owned + HBufC* iMaximumLabelText; // Owned + TInt iDecoratorImageId; + TAknFeedbackStyle iFeedbackStyle; + +private: + TInt iDecimalPlaces; + + // NOTE! This class is only for storing the data read from slider resource. + // Do not add any unnecessary members to this class, such data and + // functionality should go to the extension instead. + }; + + +// ---------------------------------------------------------------------------- +// CAknSliderData::NewLC +// ---------------------------------------------------------------------------- +// +CAknSliderData* CAknSliderData::NewLC( TInt aResourceId ) + { + CAknSliderData* self = new ( ELeave ) CAknSliderData(); + CleanupStack::PushL( self ); + self->ConstructFromResourceL( aResourceId ); + return self; + } + + +// ---------------------------------------------------------------------------- +// CAknSliderData::NewL +// ---------------------------------------------------------------------------- +// +CAknSliderData* CAknSliderData::NewL( TResourceReader& aReader ) + { + CAknSliderData* self = new ( ELeave ) CAknSliderData(); + CleanupStack::PushL( self ); + self->ConstructFromResourceL( aReader ); + CleanupStack::Pop( self ); + return self; + } + + +// ---------------------------------------------------------------------------- +// Constructor +// ---------------------------------------------------------------------------- +// +CAknSliderData::CAknSliderData() + { + // Derived from CBase -> members zeroed + } + + +// ---------------------------------------------------------------------------- +// Destructor +// ---------------------------------------------------------------------------- +// +CAknSliderData::~CAknSliderData() + { + delete iText; + delete iSingularText; + delete iMinimumLabelText; + delete iMaximumLabelText; + } + +// ---------------------------------------------------------------------------- +// CAknSliderData::ConstructFromResourceL +// ---------------------------------------------------------------------------- +// +void CAknSliderData::ConstructFromResourceL( TInt aResourceId ) + { + TResourceReader reader; + CEikonEnv::Static()->CreateResourceReaderLC( reader, aResourceId ); + ConstructFromResourceL( reader ); + CleanupStack::PopAndDestroy(); // reader + } + + +// ---------------------------------------------------------------------------- +// CAknSliderData::ConstructFromResource +// ---------------------------------------------------------------------------- +// +void CAknSliderData::ConstructFromResourceL( TResourceReader& aReader ) + { + TInt sliderType = aReader.ReadInt16(); + if ( sliderType == EAknSliderWithFeedbackStyle ) + { + iFeedbackStyle = (TAknFeedbackStyle)aReader.ReadInt16(); + iLayout = aReader.ReadInt16(); + } + else + { + // old resource struct used -> actually sliderType contains + // layout information + iLayout = sliderType; + if ( iLayout > EAknSliderLayoutHorizontal ) + { + iLayout = EAknSliderLayoutHorizontal; + } + } + + TInt min = aReader.ReadInt16(); + TInt max = aReader.ReadInt16(); + SetRange( min, max ); + iStepSize = aReader.ReadInt16(); + iValueType = aReader.ReadInt16(); + SetDecimalPlaces( aReader.ReadInt16() ); + iSingularText = aReader.ReadHBufCL(); + iMinimumLabelText = aReader.ReadHBufCL(); + iMaximumLabelText = aReader.ReadHBufCL(); + iText = aReader.ReadHBufCL(); + + // Extension link for graphics + iDecoratorImageId = aReader.ReadInt32(); + if ( !iDecoratorImageId ) + { + iDecoratorImageId = R_AVKON_SLIDER_CONTRAST_GRAPHICS; + } + } + + +// ---------------------------------------------------------------------------- +// CAknSliderData::SetRange +// ---------------------------------------------------------------------------- +// +void CAknSliderData::SetRange( TInt aMinimumValue, TInt aMaximumValue ) + { + __ASSERT_ALWAYS( aMaximumValue > aMinimumValue, + Panic( EAknPanicOutOfRange ) ); + + iMaximumValue = aMaximumValue; + iMinimumValue = aMinimumValue; + } + + +// ---------------------------------------------------------------------------- +// CAknSliderData::SetDecimalPlaces +// ---------------------------------------------------------------------------- +// +void CAknSliderData::SetDecimalPlaces( TInt aDecimalPlaces ) + { + __ASSERT_DEBUG( aDecimalPlaces >= 0, Panic( EAknPanicInvalidValue ) ); + __ASSERT_DEBUG( aDecimalPlaces < 10, Panic( EAknPanicInvalidValue ) ); + iDecimalPlaces = Abs( aDecimalPlaces ); + } + + +// ============================================================================ +NONSHARABLE_STRUCT( TAknSliderGfx ) + { + TAknSliderGfx(): iRgb( NULL ), iMask( NULL ) + {} + + CFbsBitmap* iRgb; // Referenced. + CFbsBitmap* iMask; // Referenced. + // customized graphics flag + TInt iCustomizedFlag; // if use default, then value = 0, else value = 1 + }; + +// ============================================================================ +NONSHARABLE_CLASS( CAknSliderExtension ): public CBase + { +public: + + // Symbols for bitflags. + enum TFlags + { + EFlagHorizontal, + EFlagFillEnabled, + EFlagMarkerEnabled, + EFlagTickMarksEnabled, + EFlagTickBelowOrRight, + EFlagPointerDown, + EFlagDraggingThumb, + EFlagValueStepChange, + EFlagPlayingContinuousFb, + EFlagCount // must be the last flag + }; + +private: + CAknSliderExtension(); + // Copy constructor, declared not defined -> disabled + CAknSliderExtension( const CAknSliderExtension& ); + // Assignment operator, declared not defined -> disabled + const CAknSliderExtension& operator=( const CAknSliderExtension& ); + + void ConstructL(); + +public: + ~CAknSliderExtension(); + static CAknSliderExtension* NewL(); + + void SetGraphics( TInt aElement, + CFbsBitmap* aBitmap, + CFbsBitmap* aMask, + TBool aCustomize = ETrue); + void UseDefaultGraphics( TInt aElement ); + TBool UsesDefaultGraphics( TInt aElement ) const; + TBool UsesDefaultGraphics() const; + void GetGfx( TAknSliderGfx& aGfx, TInt aElement ) const; + + void DeleteBitmaps(); + void TryLoadNSliderBitmap(TBool aFromSkin, MAknsSkinInstance* aSkin ); + void TryLoadNSliderVerticalBitmap( MAknsSkinInstance* aSkin ); + inline void SetFlag( TInt aFlagIndex ) + { + ASSERT( 0 <= aFlagIndex && aFlagIndex < EFlagCount ); + iFlags.Set( aFlagIndex ); + } + + inline void ClearFlag( TInt aFlagIndex ) + { + ASSERT( 0 <= aFlagIndex && aFlagIndex < EFlagCount ); + iFlags.Clear( aFlagIndex ); + } + + inline TBool IsFlagSet( TInt aFlagIndex ) const + { + ASSERT( 0 <= aFlagIndex && aFlagIndex < EFlagCount ); + return iFlags.IsSet( aFlagIndex ); + } + +public: + CFbsBitmap* iLineIcon; // Owned. + CFbsBitmap* iLineIconMask; // Owned. + + TRect iLeftCapRect; // The default value is zero -> no left line cap + TRect iRightCapRect; // The default value is zero -> no right line cap + + TRect iTickRect; + + CPeriodic* iTimer; // Owned. + TInt iEffectTimerCount; + TRect iThumbRect; // Equals GetMarkerRect + TUint iTickInterval; + TPoint iPenInputPos;//remember pointer input position + + TBool iReportMarkerDragEvent; + TRect iTouchDownArea; + TRect iTouchActiveArea; + TBool iNoDraw; + +private: + // If EFlagHorizontal is not set, the orientation is vertical. + TBitFlags32 iFlags; + + // Stores the element graphics (rgb icon and mask icon) as bitmaps. Bitmaps + // are owned. + TAknSliderGfx iGfx[CAknSlider::EElemMarkerSelected + 1]; + }; + + +// ---------------------------------------------------------------------------- +// CAknSliderExtension::CAknSliderExtension +// ---------------------------------------------------------------------------- +// +CAknSliderExtension::CAknSliderExtension() + { + // slider is derived from CBase -> members zeroed + SetFlag( EFlagMarkerEnabled );//default is marker enable + SetFlag( EFlagHorizontal ); //default is horizontal enable + SetFlag( EFlagValueStepChange); //default is step change enable + + // Don't report drag event as default setting + iReportMarkerDragEvent = EFalse; + } + + +// ---------------------------------------------------------------------------- +// Destructor +// ---------------------------------------------------------------------------- +// +CAknSliderExtension::~CAknSliderExtension() + { + if( iTimer ) + { + iTimer->Cancel(); + } + + delete iTimer; + delete iLineIcon; + delete iLineIconMask; + + DeleteBitmaps(); + } + + +// ---------------------------------------------------------------------------- +// CAknSliderExtension::ConstructL +// ---------------------------------------------------------------------------- +// +void CAknSliderExtension::ConstructL() + { + // Create icon for line + AknsUtils::CreateIconL( AknsUtils::SkinInstance(), + KAknsIIDQgnGrafLinePrimaryHorizontal, iLineIcon, iLineIconMask, + KAvkonBitmapFile, EMbmAvkonQgn_graf_line_primary_horizontal, + EMbmAvkonQgn_graf_line_primary_horizontal_mask ); + + // Set default value + for ( int i = 0; i <= CAknSlider::EElemMarkerSelected; ++i ) + { + iGfx[i].iRgb = NULL; + iGfx[i].iMask = NULL; + iGfx[i].iCustomizedFlag = 0; + } + + iTimer = CPeriodic::NewL( CActive::EPriorityStandard ); + } + + +// ---------------------------------------------------------------------------- +// CAknSliderExtension::NewL +// ---------------------------------------------------------------------------- +// +CAknSliderExtension* CAknSliderExtension::NewL() + { + + CAknSliderExtension* self = new( ELeave ) CAknSliderExtension(); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +// ---------------------------------------------------------------------------- +// CAknSliderExtension::TryLoadNewSliderBitmap +// +// ---------------------------------------------------------------------------- +// +void CAknSliderExtension::TryLoadNSliderBitmap( TBool aFromSkin, MAknsSkinInstance* aSkin ) + { + + const TInt iconIDArray[] = + { + EMbmAvkonQgn_graf_nslider_end_left, + EMbmAvkonQgn_graf_nslider_end_right, + EMbmAvkonQgn_graf_nslider_middle, + EMbmAvkonQgn_graf_nslider_marker, + EMbmAvkonQgn_graf_nslider_marker_selected + }; + const TInt iconMaskIDArray[] = + { + EMbmAvkonQgn_graf_nslider_end_left_mask, + EMbmAvkonQgn_graf_nslider_end_right_mask, + EMbmAvkonQgn_graf_nslider_middle_mask, + EMbmAvkonQgn_graf_nslider_marker_mask, + EMbmAvkonQgn_graf_nslider_marker_selected_mask + }; + const TAknsItemID iconSkinIDArray[] = + { + KAknsIIDQgnGrafNsliderEndLeft, + KAknsIIDQgnGrafNsliderEndRight, + KAknsIIDQgnGrafNsliderMiddle, + KAknsIIDQgnGrafNsliderMarker, + KAknsIIDQgnGrafNsliderMarkerSelected + }; + + const TInt element[] = + { + CAknSlider::EElemEmptyLeftCap, + CAknSlider::EElemEmptyRightCap, + CAknSlider::EElemEmptyLine, + CAknSlider::EElemMarker, + CAknSlider::EElemMarkerSelected + }; + TInt arrayTotal = sizeof( iconIDArray )/sizeof(TInt); + + TInt err = KErrNone; + for ( TInt i = 0; i < arrayTotal; i++ ) + { + CFbsBitmap* bitmapPtr = NULL; + CFbsBitmap* maskPtr = NULL; + + if( aFromSkin ) + { + //find new graphic from Skinned bitmap + TRAP(err, AknsUtils::CreateIconL( aSkin, + iconSkinIDArray[i], + bitmapPtr, + maskPtr, + KNullDesC, + iconIDArray[i], + iconMaskIDArray[i] )); + } + //find new graphic from mif file + else + { + TRAP(err, AknIconUtils::CreateIconL( + bitmapPtr, + maskPtr, + KAvkonBitmapFile, + iconIDArray[i], + iconMaskIDArray[i] )); + } + if( !err ) + { + SetGraphics( element[i], bitmapPtr, maskPtr ); + } + } + } + + +// ---------------------------------------------------------------------------- +// CAknSliderExtension::TryLoadNewSliderBitmap +// +// ---------------------------------------------------------------------------- +// +void CAknSliderExtension::TryLoadNSliderVerticalBitmap( MAknsSkinInstance* aSkin ) + { + + const TInt iconIDArray[] = + { + EMbmAvkonQgn_graf_nslider_vertical_top, + EMbmAvkonQgn_graf_nslider_vertical_bottom, + EMbmAvkonQgn_graf_nslider_vertical_middle, + EMbmAvkonQgn_graf_nslider_vertical_marker, + EMbmAvkonQgn_graf_nslider_vertical_tick_major, + EMbmAvkonQgn_graf_nslider_vertical_marker + }; + const TInt iconMaskIDArray[] = + { + EMbmAvkonQgn_graf_nslider_vertical_top_mask, + EMbmAvkonQgn_graf_nslider_vertical_bottom_mask, + EMbmAvkonQgn_graf_nslider_vertical_middle_mask, + EMbmAvkonQgn_graf_nslider_vertical_marker_mask, + EMbmAvkonQgn_graf_nslider_vertical_tick_major_mask, + EMbmAvkonQgn_graf_nslider_marker_mask + }; + const TAknsItemID iconSkinIDArray[] = + { + KAknsIIDNone,//KAknsIIDQgnGrafNsliderVerticalTop, + KAknsIIDNone,//KAknsIIDQgnGrafNsliderVerticalBottom, + KAknsIIDNone,//KAknsIIDQgnGrafNsliderVerticalMiddle, + KAknsIIDNone,// KAknsIIDQgnGrafNsliderVerticalMarker, + KAknsIIDNone,// KAknsIIDQgnGrafNsliderVerticalTIckMajor, + KAknsIIDNone//KAknsIIDQgnGrafNsliderVerticalMarker + }; + + const TInt element[] = + { + CAknSlider::EElemEmptyLeftCap, + CAknSlider::EElemEmptyRightCap, + CAknSlider::EElemEmptyLine, + CAknSlider::EElemMarker, + CAknSlider::EElemTickMark, + CAknSlider::EElemMarkerSelected + }; + + TInt arrayTotal = sizeof( iconIDArray )/sizeof(TInt); + + TInt err = KErrNone; + CFbsBitmap* bitmapPtr = NULL; + CFbsBitmap* maskPtr = NULL; + for ( TInt i = 0; i < arrayTotal; i++ ) + { + //find new graphic from Skinned bitmap + TRAP(err, AknsUtils::CreateIconL( aSkin, + iconSkinIDArray[i], + bitmapPtr, + maskPtr, + KNullDesC, + iconIDArray[i], + iconMaskIDArray[i] )); + + // find new graphic from mif file + if ( err ) + { + TRAP(err,AknIconUtils::CreateIconL( + bitmapPtr, + maskPtr, + KAvkonBitmapFile, + iconIDArray[i], + iconMaskIDArray[i] )); + } + if( !err ) + { + SetGraphics( element[i], bitmapPtr, maskPtr, EFalse ); + } + } + } +// ---------------------------------------------------------------------------- +// CAknSliderExtension::DeleteBitmaps +// +// ---------------------------------------------------------------------------- +// +void CAknSliderExtension::DeleteBitmaps() + { + TInt i; + + for( i = 0; i <= CAknSlider::EElemMarkerSelected; i++) + { + delete iGfx[i].iRgb; + iGfx[i].iRgb = NULL; + delete iGfx[i].iMask; + iGfx[i].iMask = NULL; + + } + } + +// ---------------------------------------------------------------------------- +// CAknSliderExtension::SetGraphics +// ---------------------------------------------------------------------------- +// +void CAknSliderExtension::SetGraphics( TInt aElement, + CFbsBitmap* aBitmap, + CFbsBitmap* aMask, + TBool aCustomize ) + { + // element index is assumed to be valid (no checking) + + // no need to set rgb or mask to NULL as we are assigning and won't leave + delete iGfx[aElement].iRgb; + iGfx[aElement].iRgb = aBitmap; + + delete iGfx[aElement].iMask; + iGfx[aElement].iMask = aMask; + + // Set the flag to 1 + iGfx[aElement].iCustomizedFlag = aCustomize; + + switch( aElement ) + { + case CAknSlider::EElemFilledLine: + { + SetFlag( EFlagFillEnabled ); + } + break; + case CAknSlider::EElemMarker: + { + SetFlag( EFlagMarkerEnabled ); + } + break; + case CAknSlider::EElemTickMark: + { + if( aBitmap==NULL && aMask==NULL ) + { + ClearFlag( EFlagTickMarksEnabled ); + } + else + { + SetFlag( EFlagTickMarksEnabled ); + } + } + break; + default: + break; + + } + } + + +// ---------------------------------------------------------------------------- +// CAknSliderExtension::UseDefaultGraphics +// ---------------------------------------------------------------------------- +// +void CAknSliderExtension::UseDefaultGraphics( TInt aElement ) + { + // element index is assumed to be valid (no checking) + + delete iGfx[aElement].iRgb; + iGfx[aElement].iRgb = NULL; + + delete iGfx[aElement].iMask; + iGfx[aElement].iMask = NULL; + + iGfx[aElement].iCustomizedFlag = 0; + } + + + +// ---------------------------------------------------------------------------- +// CAknSliderExtension::UsesDefaultGraphics +// ---------------------------------------------------------------------------- +// +TBool CAknSliderExtension::UsesDefaultGraphics( TInt aElement ) const + { + // element index is assumed to be valid (no checking) + + if ( iGfx[aElement].iCustomizedFlag == 0 ) + { + return ETrue; + } + return EFalse; + } + +// ---------------------------------------------------------------------------- +// CAknSliderExtension::UsesDefaultGraphics +// ---------------------------------------------------------------------------- +// +TBool CAknSliderExtension::UsesDefaultGraphics() const + { + // element index is assumed to be valid (no checking) + + TBool ret(ETrue); + + ret = ret && UsesDefaultGraphics( CAknSlider::EElemEmptyLeftCap ) && + UsesDefaultGraphics( CAknSlider::EElemEmptyRightCap ) && + UsesDefaultGraphics( CAknSlider::EElemEmptyLine ); + + return ret; + } + +// ---------------------------------------------------------------------------- +// CAknSliderExtension::GetGfx +// ---------------------------------------------------------------------------- +// +void CAknSliderExtension::GetGfx( TAknSliderGfx& aGfx, TInt aElement ) const + { + // element index is assumed to be valid (no checking) + + aGfx = iGfx[aElement]; + } + + +// ============================================================================ +// An internal helper class for creating slider graphics for option setting +// item. +NONSHARABLE_CLASS( CAknSliderIconizer ): public CBase + { +public: + static void CreateSettingsIconL( const TRect& aRect, TInt aValue, + CGulIcon* aIcon, const TInt aMinValue, + const TInt aMaxValue ); + + static void ReSizeDefaultSettingsIcons( const TRect& aParent, + CAknSliderIconizer* aIcon ); + static void ReSizeNewSettingsIcons( const TRect& aParent, + CAknSliderExtension* aExtension, + CAknSliderIconizer* aIcon, + TInt aValue, + const TInt aMinValue, + const TInt aMaxValue ); +private: + CAknSliderIconizer(); + ~CAknSliderIconizer(); + void DrawSettingsIconL( const TRect& aRect, TInt aValue, CGulIcon* aIcon, + const TInt aMinValue, const TInt aMaxValue , + TBool aFlagFilled ) const; + + void DrawDefaultSettingsIconL( const TRect& aParent, + TInt aValue, + CFbsBitGc* aFbsBitGc, + const TInt aMinValue, + const TInt aMaxValue ) const; + void DrawNewSettingsIconL( const TRect& aParent, + TInt aValue, + CFbsBitGc* aFbsBitGc, + const TInt aMinValue, + const TInt aMaxValue, + TBool aFilledFlag ) const; + +private: + // Stores the element graphics (rgb icon and mask icon) as bitmaps. Bitmaps + // are owned. + TAknSliderGfx iSettingGfx[CAknSlider::EElemMarkerSelected + 1]; + + }; + + +// ---------------------------------------------------------------------------- +// Constructor +// ---------------------------------------------------------------------------- +// +CAknSliderIconizer::CAknSliderIconizer() + { + // Derived from CBase -> members zeroed + } + + +// ---------------------------------------------------------------------------- +// Destructor +// ---------------------------------------------------------------------------- +// +CAknSliderIconizer::~CAknSliderIconizer() + { + } + + +// ---------------------------------------------------------------------------- +// CAknSliderIconizer::CreateSettingsIconL +// ---------------------------------------------------------------------------- +// +void CAknSliderIconizer::CreateSettingsIconL( + const TRect& aRect, TInt aValue, CGulIcon* aIcon, + const TInt aMinValue, const TInt aMaxValue ) + { + MAknsSkinInstance* skin = AknsUtils::SkinInstance(); + + CAknSliderIconizer* iconizer = new ( ELeave ) CAknSliderIconizer; + CleanupStack::PushL( iconizer ); + + // Set default value + for ( int i = 0; i <= CAknSlider::EElemMarkerSelected; ++i ) + { + iconizer->iSettingGfx[i].iRgb = NULL; + iconizer->iSettingGfx[i].iMask = NULL; + iconizer->iSettingGfx[i].iCustomizedFlag = 0; + } + + // aRect = set_value_pane + TAknLayoutRect layoutRect; + layoutRect.LayoutRect( aRect, + AknLayoutScalable_Avkon::slider_set_pane_cp3() ); + TRect sliderPane = layoutRect.Rect(); + CAknSliderExtension* extension = CAknSliderExtension::NewL(); + CleanupStack::PushL( extension ); + + // Load bitmaps + //1.load new graphics from skin + extension->TryLoadNSliderBitmap( ETrue, skin ); + + if( extension->UsesDefaultGraphics() ) + { + //2. load old graphic from skin + TRAPD( err, { + AknsUtils::CreateIconL( skin, + KAknsIIDQgnIndiSliderSet, + iconizer->iSettingGfx[CAknSlider::EElemMarker].iRgb, + iconizer->iSettingGfx[CAknSlider::EElemMarker].iMask, + KNullDesC, + EMbmAvkonQgn_indi_slider_edit, + EMbmAvkonQgn_indi_slider_edit_mask ); + + AknsUtils::CreateIconL( skin, + KAknsIIDQgnGrafLinePrimaryHorizontal, + iconizer->iSettingGfx[CAknSlider::EElemEmptyLine].iRgb, + iconizer->iSettingGfx[CAknSlider::EElemEmptyLine].iMask, + KNullDesC, + EMbmAvkonQgn_graf_line_primary_horizontal, + EMbmAvkonQgn_graf_line_primary_horizontal_mask ); + } ); + if( !err ) + { + ReSizeDefaultSettingsIcons( sliderPane, iconizer ); + } + + //3.load new from mif, must success + + else + { + extension->TryLoadNSliderBitmap( EFalse, skin ); + } + } + + + //new slider layout + ReSizeNewSettingsIcons( sliderPane, extension, iconizer, + aValue, aMinValue,aMaxValue ); + + iconizer->DrawSettingsIconL( aRect, + aValue, + aIcon, + aMinValue, + aMaxValue, + extension->IsFlagSet(CAknSliderExtension::EFlagFillEnabled)); + + CleanupStack::PopAndDestroy(); // extension, the bitmaps loaded deleted here + if( iconizer->iSettingGfx[CAknSlider::EElemMarker].iCustomizedFlag == 0 ) + { + delete iconizer->iSettingGfx[CAknSlider::EElemMarker].iRgb; + iconizer->iSettingGfx[CAknSlider::EElemMarker].iRgb = NULL; + delete iconizer->iSettingGfx[CAknSlider::EElemMarker].iMask; + iconizer->iSettingGfx[CAknSlider::EElemMarker].iMask = NULL; + } + if( iconizer->iSettingGfx[CAknSlider::EElemEmptyLine].iCustomizedFlag == 0 ) + { + delete iconizer->iSettingGfx[CAknSlider::EElemEmptyLine].iRgb; + iconizer->iSettingGfx[CAknSlider::EElemEmptyLine].iRgb = NULL; + delete iconizer->iSettingGfx[CAknSlider::EElemEmptyLine].iMask; + iconizer->iSettingGfx[CAknSlider::EElemEmptyLine].iMask = NULL; + } + CleanupStack::PopAndDestroy( iconizer ); + } +// ---------------------------------------------------------------------------- +// CAknSliderIconizer::ReSizeDefaultSettingsIcons +// ---------------------------------------------------------------------------- +// +void CAknSliderIconizer::ReSizeDefaultSettingsIcons( const TRect& aParent, + CAknSliderIconizer* aIcon ) + { + TAknLayoutRect temp; + TRect lineRect,markerRect; + //old slider layout + temp.LayoutRect( aParent, + AknLayoutScalable_Avkon::slider_set_pane_g1() ); + lineRect = temp.Rect(); + temp.LayoutRect( aParent, + AknLayoutScalable_Avkon::slider_set_pane_g2() ); + markerRect = temp.Rect(); + if( aIcon->iSettingGfx[CAknSlider::EElemEmptyLine].iRgb != NULL && + aIcon->iSettingGfx[CAknSlider::EElemMarker].iRgb != NULL ) + { + AknIconUtils::SetSize( aIcon->iSettingGfx[CAknSlider::EElemEmptyLine].iRgb, + lineRect.Size(), + EAspectRatioNotPreserved ); + AknIconUtils::SetSize( aIcon->iSettingGfx[CAknSlider::EElemMarker].iRgb, + markerRect.Size() ); + } + } + +// ---------------------------------------------------------------------------- +// CAknSliderIconizer::ReSizeNewSettingsIcons +// ---------------------------------------------------------------------------- +// +void CAknSliderIconizer::ReSizeNewSettingsIcons( const TRect& aParent, + CAknSliderExtension* aExtentsion, + CAknSliderIconizer* aIcon,TInt aValue, + const TInt aMinValue, + const TInt aMaxValue ) + { + TAknLayoutRect temp; + TRect lineRect,markerRect,leftCapRect,rightCapRect,tickRect; + temp.LayoutRect( aParent, + AknLayoutScalable_Avkon::slider_set_pane_g4() ); + lineRect = temp.Rect(); + + temp.LayoutRect( aParent, + AknLayoutScalable_Avkon::slider_set_pane_g3() ); + leftCapRect = temp.Rect(); + + temp.LayoutRect( aParent, + AknLayoutScalable_Avkon::slider_set_pane_g5() ); + rightCapRect = temp.Rect(); + + temp.LayoutRect( aParent, + AknLayoutScalable_Avkon::slider_set_pane_g6() ); + markerRect = temp.Rect(); + + temp.LayoutRect( aParent, + AknLayoutScalable_Avkon::slider_set_pane_g7() ); + + tickRect = temp.Rect(); + + TSize size; + for ( int i = 0; i <= CAknSlider::EElemMarkerSelected; ++i ) + { + if( !aExtentsion->UsesDefaultGraphics(i) ) + { + aExtentsion->GetGfx( aIcon->iSettingGfx[i], i ); + + switch( i ) + { + case CAknSlider::EElemEmptyLine: + { + size = lineRect.Size(); + break; + } + case CAknSlider::EElemMarker: + case CAknSlider::EElemMarkerSelected: + { + size = markerRect.Size(); + break; + } + case CAknSlider::EElemTickMark: + { + size = tickRect.Size(); + break; + } + case CAknSlider::EElemEmptyLeftCap: + { + size = leftCapRect.Size(); + break; + } + case CAknSlider::EElemEmptyRightCap: + { + size = rightCapRect.Size(); + break; + } + case CAknSlider::EElemFilledLeftCap: + { + size = leftCapRect.Size(); + break; + } + case CAknSlider::EElemFilledRightCap: + { + size = rightCapRect.Size(); + break; + } + case CAknSlider::EElemFilledLine: + { + TInt bmpRun = lineRect.Width() + + leftCapRect.Width() + + rightCapRect.Width() - + markerRect.Width(); + TInt pos = ( ( bmpRun * ( aValue - aMinValue ) ) / + (aMaxValue - aMinValue ) ); + + TPoint markerPos = TPoint( pos + markerRect.iTl.iX, markerRect.iTl.iY ); + + size.iWidth = markerPos.iX + (markerRect.Width()/2) - + lineRect.iTl.iX; + size.iHeight = lineRect.Height(); + break; + } + default: + Panic( EAknPanicInvalidValue ); + } + if( aIcon->iSettingGfx[i].iRgb != NULL && + aIcon->iSettingGfx[i].iMask != NULL ) + { + AknIconUtils::SetSize( aIcon->iSettingGfx[i].iRgb, + size, + EAspectRatioNotPreserved ); + AknIconUtils::SetSize( aIcon->iSettingGfx[i].iMask, + size, + EAspectRatioNotPreserved ); + aIcon->iSettingGfx[i].iCustomizedFlag = 1; + } + } + } + } +// ---------------------------------------------------------------------------- +// CAknSliderIconizer::DrawSettingsIconL +// ---------------------------------------------------------------------------- +// +void CAknSliderIconizer::DrawSettingsIconL( + const TRect& aRect, TInt aValue, CGulIcon* aIcon, + const TInt aMinValue, const TInt aMaxValue, TBool aFilledFlag ) const + { + // The actual bitmap + CFbsBitmap* bitmap = new ( ELeave ) CFbsBitmap; + CleanupStack::PushL( bitmap ); + + User::LeaveIfError( 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 outerRect; + TRect innerRect; + 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 ) ); + TRect listSettingPaneRect( layoutRect.Rect() ); + + // 1. Background skinning + TAknLayoutRect innerLayRect; + + // New style LAF data used +#ifdef RD_LIST_STRETCH + + // check list stretching from cenrep + TBool stretchingEnabled; + CRepository* cenRep = CRepository::NewL( KCRUidAvkon ); + cenRep->Get( KAknAutomaticListStretching, stretchingEnabled ); + delete cenRep; + + if ( Layout_Meta_Data::IsLandscapeOrientation() && + Layout_Meta_Data::IsListStretchingEnabled() && + stretchingEnabled ) + { + layoutRect.LayoutRect( listSettingPaneRect, + AknLayoutScalable_Avkon::set_value_pane_vc( 0 ) ); + } + else + { + layoutRect.LayoutRect( listSettingPaneRect, + AknLayoutScalable_Avkon::set_value_pane( 0 ) ); + } +#else + layoutRect.LayoutRect( listSettingPaneRect, + AknLayoutScalable_Avkon::set_value_pane( 0 ) ); +#endif + layoutRect.LayoutRect( layoutRect.Rect(), + AknLayoutScalable_Avkon::bg_set_opt_pane( 0 ) ); + innerLayRect.LayoutRect( layoutRect.Rect(), + AknLayoutScalable_Avkon::bg_set_opt_pane_g1() ); + + // Move to 0,0 + outerRect = layoutRect.Rect(); + TPoint skinOffset( -outerRect.iTl.iX, -outerRect.iTl.iY ); + + innerRect = innerLayRect.Rect(); + + outerRect.Move( skinOffset ); + innerRect.Move( skinOffset ); + + + // Frame IID for qsn_fr_set_opt_foc_xxxxx + const TAknsItemID *frameId = &KAknsIIDQsnFrSetOptFoc; + + // Make a control context: + CAknsFrameBackgroundControlContext* cc = + CAknsFrameBackgroundControlContext::NewL( + *frameId, outerRect, innerRect, EFalse ); + CleanupStack::PushL( cc ); + + TPoint dstPos( 0, 0 ); + + AknsDrawUtils::DrawBackground( AknsUtils::SkinInstance(), cc, NULL, + *fbsBitGc, dstPos, outerRect, KAknsDrawParamDefault ); + CleanupStack::PopAndDestroy(); // cc + + // 2. Draw the line and marker on top of the background + // aRect = set_value_pane + layoutRect.LayoutRect( aRect, + AknLayoutScalable_Avkon::slider_set_pane_cp3() ); + TRect parent = layoutRect.Rect(); + + + //new graphic or old + if( iSettingGfx[CAknSlider::EElemEmptyLeftCap].iCustomizedFlag != 1 && + iSettingGfx[CAknSlider::EElemEmptyRightCap].iCustomizedFlag != 1 ) + { + DrawDefaultSettingsIconL( parent, aValue, fbsBitGc, + aMinValue, aMaxValue ); + } + else + { + DrawNewSettingsIconL( parent, aValue, fbsBitGc, aMinValue, + aMaxValue, aFilledFlag ); + } + + + CleanupStack::PopAndDestroy( 2 ); // bmpDevice, fbsBitGc + + // Transfers ownership, so all we need to do is to.. + aIcon->SetBitmap( bitmap ); + CleanupStack::Pop(); // bitmap + + // 3. The mask + CFbsBitmap* mask = new ( ELeave ) CFbsBitmap; + CleanupStack::PushL( mask ); + + TDisplayMode mode = iSettingGfx[CAknSlider::EElemEmptyLine].iMask->DisplayMode(); + if ( mode == ENone ) + { + mode = EGray256; + } + + User::LeaveIfError( mask->Create( aRect.Size(), mode ) ); + 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( KRgbWhite ); + fbsBitGc->DrawRect( TRect( aRect.Size() ) ); + fbsBitGc->SetBrushStyle( CGraphicsContext::ENullBrush ); + + AknsDrawUtils::DrawFrame( AknsUtils::SkinInstance(), *fbsBitGc, + outerRect, innerRect, + KAknsIIDQsnFrSetOptFoc, + KAknsIIDQsnFrSetOptFocCenter, + KAknsSDMAlphaOnly ); + + CleanupStack::PopAndDestroy( 2 ); // bmpDevice, fbsBitGc + + // Transfers ownership, so all we need to do is to.. + aIcon->SetMask( mask ); + CleanupStack::Pop(); // mask + + } + // ---------------------------------------------------------------------------- +// CAknSliderIconizer::DrawDefaultSettingsIconL +// ---------------------------------------------------------------------------- +// +void CAknSliderIconizer::DrawDefaultSettingsIconL( + const TRect& aParent, TInt aValue, CFbsBitGc* aFbsBitGc, + const TInt aMinValue, const TInt aMaxValue ) const + { + TRect lineRect, markerRect; + TInt bitmapRun; + TAknLayoutRect layoutRect; + + layoutRect.LayoutRect( aParent, + AknLayoutScalable_Avkon::slider_set_pane_g1() ); + + lineRect = layoutRect.Rect(); + TAknLayoutRect markerLayout; + markerLayout.LayoutRect( aParent, + AknLayoutScalable_Avkon::slider_set_pane_g2() ); + markerRect = markerLayout.Rect(); + bitmapRun = lineRect.Width() - markerRect.Width(); + + //new graphic and old graphic is in the same place + aFbsBitGc->BitBltMasked( TPoint( lineRect.iTl.iX, lineRect.iTl.iY ), + iSettingGfx[CAknSlider::EElemEmptyLine].iRgb, + TRect( 0, 0, lineRect.Width(), lineRect.Height()), + iSettingGfx[CAknSlider::EElemEmptyLine].iMask, + EFalse); + // Calculate the correct position where to draw the marker + + TInt range = aMaxValue - aMinValue; + // It is this expression which determines the functional direction of + // the slider in its drawing (but not its event handling). + TInt pos = ( ( bitmapRun * ( aValue - aMinValue ) ) / range ); + + TPoint markerPos = TPoint( pos + markerRect.iTl.iX, markerRect.iTl.iY ); + TRect srcRect( 0, 0, markerRect.Width(), markerRect.Height() ); + + aFbsBitGc->BitBltMasked( markerPos, + iSettingGfx[CAknSlider::EElemMarker].iRgb, + srcRect, + iSettingGfx[CAknSlider::EElemMarker].iMask, + EFalse); + } +// ---------------------------------------------------------------------------- +// CAknSliderIconizer::DrawNewSettingsIconL +// ---------------------------------------------------------------------------- +// +void CAknSliderIconizer::DrawNewSettingsIconL( + const TRect& aParent, TInt aValue, CFbsBitGc* aFbsBitGc, + const TInt aMinValue, const TInt aMaxValue, TBool aFilledFlag ) const + { + TRect lineRect, markerRect, leftCapRect, rightCapRect, tickRect; + TInt bitmapRun; + TAknLayoutRect layoutRect; + + layoutRect.LayoutRect( aParent, + AknLayoutScalable_Avkon::slider_set_pane_g4() ); + lineRect = layoutRect.Rect(); + + layoutRect.LayoutRect( aParent, + AknLayoutScalable_Avkon::slider_set_pane_g3() ); + leftCapRect = layoutRect.Rect(); + + layoutRect.LayoutRect( aParent, + AknLayoutScalable_Avkon::slider_set_pane_g5() ); + rightCapRect = layoutRect.Rect(); + + layoutRect.LayoutRect( aParent, + AknLayoutScalable_Avkon::slider_set_pane_g6() ); + markerRect = layoutRect.Rect(); + + layoutRect.LayoutRect( aParent, + AknLayoutScalable_Avkon::slider_set_pane_g7() ); + + tickRect = layoutRect.Rect(); + bitmapRun = lineRect.Width() + + leftCapRect.Width() + + rightCapRect.Width() - + markerRect.Width(); + + //new graphic and old graphic is in the same place + aFbsBitGc->BitBltMasked( TPoint( lineRect.iTl.iX, lineRect.iTl.iY ), + iSettingGfx[CAknSlider::EElemEmptyLine].iRgb, + TRect( 0, 0, lineRect.Width(), lineRect.Height()), + iSettingGfx[CAknSlider::EElemEmptyLine].iMask, + EFalse); + //leftcap, rightcap,filled line,tick + aFbsBitGc->BitBltMasked( TPoint( leftCapRect.iTl.iX, leftCapRect.iTl.iY ), + iSettingGfx[CAknSlider::EElemEmptyLeftCap].iRgb, + TRect(0, 0, leftCapRect.Width(), leftCapRect.Height()), + iSettingGfx[CAknSlider::EElemEmptyLeftCap].iMask, + EFalse); + aFbsBitGc->BitBltMasked( TPoint( rightCapRect.iTl.iX, rightCapRect.iTl.iY ), + iSettingGfx[CAknSlider::EElemEmptyRightCap].iRgb, + TRect( 0, 0, rightCapRect.Width(), rightCapRect.Height()), + iSettingGfx[CAknSlider::EElemEmptyRightCap].iMask, + EFalse ); + // Calculate the correct position where to draw the marker + + TInt range = aMaxValue - aMinValue; + // It is this expression which determines the functional direction of + // the slider in its drawing (but not its event handling). + TInt pos = ( ( bitmapRun * ( aValue - aMinValue ) ) / range ); + + TPoint markerPos = TPoint( pos + markerRect.iTl.iX, markerRect.iTl.iY ); + + //filled enable, draw filled line + if( aFilledFlag ) + { + // filled line and cap + TInt fillWidth = markerPos.iX + markerRect.Width()/2 - lineRect.iTl.iX; + aFbsBitGc->BitBltMasked( TPoint( lineRect.iTl.iX, lineRect.iTl.iY ), + iSettingGfx[CAknSlider::EElemFilledLine].iRgb, + TRect(0, 0, fillWidth, lineRect.Height()), + iSettingGfx[CAknSlider::EElemFilledLine].iMask, + EFalse); + //left cap always filled + if( aValue != aMinValue ) + { + aFbsBitGc->BitBltMasked( TPoint( lineRect.iTl.iX, lineRect.iTl.iY ), + iSettingGfx[CAknSlider::EElemFilledLeftCap].iRgb, + TRect(0, 0, leftCapRect.Width(), leftCapRect.Height()), + iSettingGfx[CAknSlider::EElemFilledLine].iMask, + EFalse); + } + + //only when the line filled, the right cap filled + if( aValue >= aMaxValue ) + { + aFbsBitGc->BitBltMasked( TPoint( lineRect.iTl.iX, lineRect.iTl.iY ), + iSettingGfx[CAknSlider::EElemFilledRightCap].iRgb, + TRect( 0, 0, rightCapRect.Width(), rightCapRect.Height()), + iSettingGfx[CAknSlider::EElemFilledLine].iMask, + EFalse); + } + + } + else + { + TRect srcRect( 0, 0, markerRect.Width(), markerRect.Height() ); + + aFbsBitGc->BitBltMasked( markerPos, + iSettingGfx[CAknSlider::EElemMarker].iRgb, + srcRect, + iSettingGfx[CAknSlider::EElemMarker].iMask, + EFalse); + } + + + } +// ============================================================================ + +// ---------------------------------------------------------------------------- +// Default constructor +// ---------------------------------------------------------------------------- +// +EXPORT_C CAknSlider::CAknSlider() + { + // Derived from CBase -> members zeroed + AKNTASHOOK_ADD( this, "CAknSlider" ); + } + + +// ---------------------------------------------------------------------------- +// Destructor +// ---------------------------------------------------------------------------- +// +EXPORT_C CAknSlider::~CAknSlider() + { + AKNTASHOOK_REMOVE(); + AknsUtils::DeregisterControlPosition( this ); + delete iValueLabel; + delete iMinLabel; + delete iMaxLabel; + delete iMarkerBmp; + delete iMarkerMaskBmp; + delete iImage; + delete iData; + delete iExt; + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::ConstructL +// Creates the labels. +// ---------------------------------------------------------------------------- +// +void CAknSlider::ConstructL() + { + iExt = CAknSliderExtension::NewL(); + + InitializeBitmapsL(); + + + iValueLabel = new( ELeave ) CEikLabel; + iValueLabel->UseLogicalToVisualConversion( EFalse ); + iValueLabel->SetContainerWindowL( *this ); + + iMinLabel = new( ELeave ) CEikLabel; + iMinLabel->SetContainerWindowL( *this ); + + iMaxLabel = new( ELeave ) CEikLabel; + iMaxLabel->SetContainerWindowL( *this ); + + if ( AknLayoutUtils::PenEnabled() && ( &Window() != NULL ) ) + { + // 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 ); + } + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::InitializeBitmapsL +// ---------------------------------------------------------------------------- +// +void CAknSlider::InitializeBitmapsL() + { + + if ( iExt->iLineIcon ) + { + delete iExt->iLineIcon; + iExt->iLineIcon = NULL; + delete iExt->iLineIconMask; + iExt->iLineIconMask = NULL; + } + iExt->DeleteBitmaps(); + + MAknsSkinInstance* skin = AknsUtils::SkinInstance(); + + if( Layout() == EAknSliderLayoutVertical ) //vertical + { + //1.load default graphic for new vertical slider + iExt->ClearFlag( CAknSliderExtension::EFlagHorizontal ); + iExt->TryLoadNSliderVerticalBitmap( skin ); + + } + + else if ( Layout() == EAknSliderLayoutHorizontal ) + { + iExt->TryLoadNSliderBitmap( ETrue, skin ); + } + + else // horizonal + { + //1.load new from skin + iExt->TryLoadNSliderBitmap( ETrue, skin ); + if( iExt->UsesDefaultGraphics() ) + { + //2.load old from skin + TRAPD( err, + { + AknsUtils::CreateIconL( skin, + KAknsIIDQgnGrafLinePrimaryHorizontal, + iExt->iLineIcon, + iExt->iLineIconMask, + KNullDesC, + EMbmAvkonQgn_graf_line_primary_horizontal, + EMbmAvkonQgn_graf_line_primary_horizontal_mask); + AknsUtils::CreateIconL( skin, + KAknsIIDQgnIndiSliderEdit, + iMarkerBmp, + iMarkerMaskBmp, + KNullDesC, + EMbmAvkonQgn_indi_slider_edit, + EMbmAvkonQgn_indi_slider_edit_mask); + + } ); + //3.load new from mif, must success. + if( err ) + { + + iExt->TryLoadNSliderBitmap( EFalse, skin ); + } + } + + } + + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::SetValueL +// ---------------------------------------------------------------------------- +// +EXPORT_C void CAknSlider::SetValueL( TInt aValue ) + { + // Note that this assert will panic any value that is not aligned on the + // step size relative to the minimum value; + __ASSERT_DEBUG( aValue >= MinimumValue() && + aValue<= MaximumValue() && + ( aValue-MinimumValue() ) % StepSize() == 0, + Panic( EAknPanicOutOfRange ) ); + iValue = aValue; + if ( iValueLabel != NULL ) + { + SetValueTextL(); + } + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::Value +// ---------------------------------------------------------------------------- +// +EXPORT_C TInt CAknSlider::Value() const + { + return iValue; + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::CreateBitmapL +// Returns slider bitmap to "list pane for setting item" (setting option item +// slider graphic). Ownership of the bitmap is transferred to the caller. +// ---------------------------------------------------------------------------- +// +EXPORT_C CFbsBitmap* CAknSlider::CreateBitmapL( TInt aValue, TInt aResourceId ) + { + TResourceReader reader; + CEikonEnv::Static()->CreateResourceReaderLC( reader, aResourceId ); + + reader.ReadInt16(); // ignore layout + TInt minValue = reader.ReadInt16(); + TInt maxValue = reader.ReadInt16(); + CleanupStack::PopAndDestroy(); // reader + + return CreateBitmapL( aValue, minValue, maxValue ); + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::CreateBitmapL +// Returns slider bitmap to "list pane for setting item" (setting option item +// slider graphic). Ownership of the bitmap is transferred to the caller. +// ---------------------------------------------------------------------------- +// +EXPORT_C CFbsBitmap* CAknSlider::CreateBitmapL( + TInt aValue, TInt aMinimumValue, TInt aMaximumValue ) + { + CGulIcon* icon = CreateSetStyleListBoxIconL( + aValue, aMinimumValue, aMaximumValue ); // now have ownership + icon->SetBitmapsOwnedExternally( ETrue ); + CFbsBitmap* bitmap = icon->Bitmap(); + CFbsBitmap* mask = icon->Mask(); + delete icon; + delete mask; + return bitmap; // ownership transferred + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::CreateSetStyleListBoxIconL +// Returns slider icon to "list pane for setting item" (setting option item +// slider graphic). Ownership of the icon is transferred to the caller. +// ---------------------------------------------------------------------------- +// +EXPORT_C CGulIcon* CAknSlider::CreateSetStyleListBoxIconL( + TInt aValue, TInt aResourceId ) + { + TResourceReader reader; + CEikonEnv::Static()->CreateResourceReaderLC( reader, aResourceId ); + + reader.ReadInt16(); // ignore layout + TInt minValue = reader.ReadInt16(); + TInt maxValue = reader.ReadInt16(); + CleanupStack::PopAndDestroy(); // reader + + return CreateSetStyleListBoxIconL( aValue, minValue, maxValue ); + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::CreateSetStyleListBoxIconL +// Returns slider icon to "list pane for setting item" (setting option item +// slider graphic). Ownership of the icon is transferred to the caller. +// ---------------------------------------------------------------------------- +// +EXPORT_C CGulIcon* CAknSlider::CreateSetStyleListBoxIconL( + TInt aValue, TInt aMinimumValue, TInt aMaximumValue ) + { + __ASSERT_ALWAYS( aMaximumValue > aMinimumValue, + Panic( EAknPanicOutOfRange ) ); + __ASSERT_ALWAYS( ( aValue <= aMaximumValue ) && + ( aValue >= aMinimumValue ), + Panic( EAknPanicOutOfRange ) ); + + // 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 ) ); + TRect listSettingPaneRect( layoutRect.Rect()); +#ifdef RD_LIST_STRETCH + // check list stretching from cenrep + TBool stretchingEnabled; + CRepository* cenRep = CRepository::NewL( KCRUidAvkon ); + cenRep->Get( KAknAutomaticListStretching, stretchingEnabled ); + delete cenRep; + + if ( Layout_Meta_Data::IsLandscapeOrientation() && + Layout_Meta_Data::IsListStretchingEnabled() && + stretchingEnabled ) + { + layoutRect.LayoutRect( layoutRect.Rect(), + AknLayoutScalable_Avkon::set_value_pane_vc( 0 ) ); + } + else + { + layoutRect.LayoutRect( layoutRect.Rect(), + AknLayoutScalable_Avkon::set_value_pane( 0 ) ); + } +#else + layoutRect.LayoutRect( layoutRect.Rect(), + AknLayoutScalable_Avkon::set_value_pane( 0 ) ); +#endif + TRect setValuePaneRect( layoutRect.Rect() ); + TRect rect( setValuePaneRect ); + + // Move to 0,0 + rect.Move( -rect.iTl.iX, -rect.iTl.iY ); + CAknSliderIconizer::CreateSettingsIconL( rect, aValue, icon, + aMinimumValue, aMaximumValue ); + CleanupStack::Pop( icon ); // icon - not owned anymore, do not destroy + return icon; // ownership transferred + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::SetRange +// ---------------------------------------------------------------------------- +// +EXPORT_C void CAknSlider::SetRange( TInt aMinimumValue, TInt aMaximumValue ) + { + SliderData()->SetRange( aMinimumValue, aMaximumValue ); + } + +// ---------------------------------------------------------------------------- +// CAknSlider::GetRange +// ---------------------------------------------------------------------------- +// +EXPORT_C void CAknSlider::GetRange( TInt& aMinimumValue, TInt& aMaximumValue ) + { + aMaximumValue = MaximumValue(); + aMinimumValue = MinimumValue(); + } + +// ---------------------------------------------------------------------------- +// CAknSlider::SetStepSize +// ---------------------------------------------------------------------------- +// +EXPORT_C void CAknSlider::SetStepSize( TInt aStepSize ) + { + // This assert is only done for CAknSlider, as the step size is not + // particularly relevant for the data; That is, if you are just interested + // in CAknSliderData in order to format a value label, then you might want + // to ignore the restrictions on stepsize + __ASSERT_ALWAYS( aStepSize != 0 && SliderData()->Range() % aStepSize == 0, + Panic( EAknPanicOutOfRange ) ); + SliderData()->iStepSize = aStepSize; + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::SetValueTextL +// Sets the text for the value label. +// ---------------------------------------------------------------------------- +// +EXPORT_C void CAknSlider::SetValueTextL() + { + TBuf textBuf; + DoSetValueTextL( textBuf, iValue, *SliderData() ); + AknBidiTextUtils::ConvertToVisualAndClipL( textBuf, + *( iValueLabel->Font() ), + iValueLabel->Size().iWidth, + iValueLabel->Size().iWidth ); + iValueLabel->SetTextL( textBuf ); + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::DoSetValueTextL +// ---------------------------------------------------------------------------- +// +void CAknSlider::DoSetValueTextL( TDes& aTextBuf, TInt aValue, + const CAknSliderData& aSliderData ) + { + TBuf valueBuf; + _LIT( KBareFigure, "%d" ); + _LIT( KFraction, "%d/%d" ); + + switch ( aSliderData.iValueType ) + { + case EAknSliderValueBareFigure: + valueBuf.Format( KBareFigure, aValue ); // bare figure + break; + + case EAknSliderValuePercentage: + { + TInt num = ( 100 * ( aValue - aSliderData.iMinimumValue ) ) / + aSliderData.Range(); + HBufC* percentage = StringLoader::LoadLC( R_QTN_SELECT_SLIDER_VALUE,num ); + valueBuf.Copy( *percentage ); + CleanupStack::PopAndDestroy( percentage ); + } + break; + + case EAknSliderValueFraction: + valueBuf.Format( KFraction, aValue, aSliderData.iMaximumValue ); // x/y + break; + + case EAknSliderValueDecimal: + { + TReal r; + Math::Pow10( r, aSliderData.DecimalPlaces() ); + // First have to format the format. + TBuf<8> format; + // This allows for 2 digit field size and/or decimal places + _LIT( KFormatTemplate, "%%-%d.%df" ); + format.Format( KFormatTemplate, + KAknSliderValueLabelValueMaxLength, + aSliderData.DecimalPlaces() ); + valueBuf.Format( format, aValue / r ); + valueBuf.TrimAll(); + } + break; + default: + break; // valueBuf left empty + } // end switch + + // Convert this formatted number if necessary to display language-sensitive + // numerals + AknTextUtils::DisplayTextLanguageSpecificNumberConversion( valueBuf ); + + // A text pointer for the format string + TPtr formatPtr( 0, 0 ); + + if ( aSliderData.iText != NULL ) + { + formatPtr.Set( aSliderData.iText->Des() ); + } + + if ( aSliderData.iSingularText != NULL ) + { + // format with %U in the supplied text. But only if value = 1 and we + // are using bare figure layout + if ( ( aValue == 1 ) && + ( aSliderData.iValueType == EAknSliderValueBareFigure ) ) + { + formatPtr.Set( aSliderData.iSingularText->Des() ); + } + } + + if ( formatPtr.Length() > 0 ) + { + FormatWithOrWithoutTokenL( aTextBuf, formatPtr, valueBuf ); + } + else + { + aTextBuf.Copy( valueBuf.Left( KAknSliderValueLabelValueMaxLength ) ); + } + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::FormatWithOrWithoutTokenL +// +// This method is used to protect the call to StringLoader::Format against +// passing it texts with no token. If you do, it panics. +// +// The protection here is still far from perfect, as only % is looked for. So +// there is still a problem. +// +// StringLoader itself should take on this responsibility and not panic. In +// this case, the call to this routine would just be the code in the 2nd half. +// ---------------------------------------------------------------------------- +// +void CAknSlider::FormatWithOrWithoutTokenL( + TDes& aOutput, const TDesC& aFormat, const TDesC& aValue ) + { + if ( aFormat.Locate('%') == -1 ) + { + aOutput.Copy( aFormat.Left( KValueLabelTextMaxLength ) ); + } + else + { + // We can know that the length of the resulting formatted string will + // be less than or equal to the sum of the two lengths Wierd effects in + // string loader mean we have to add 2 more (It adds key length instead + // of subtracting it sometimes).... + TInt safeLength = aValue.Length() + aFormat.Length() + + KAknSliderFormatKeyLength; + + // No leaving methods are going to be called + HBufC* wholeTextBuf = HBufC::NewL( safeLength ); + TPtr wholeTextPtr = wholeTextBuf->Des(); + + // Value for when no %U or when there is no number (%NU) + TInt keyIndex = -1; + StringLoader::Format( wholeTextPtr, aFormat, keyIndex, aValue ); + aOutput.Copy( wholeTextPtr.Left( KValueLabelTextMaxLength ) ); + + delete wholeTextBuf; + } + } + + +// ---------------------------------------------------------------------------- +// DoSetLabelTextL +// Local function to gather together arabization of minimum/maximum strings. +// Static to make the function local to this compilation unit only (i.e. not +// polluting the global namespace). +// ---------------------------------------------------------------------------- +static void DoSetLabelTextL( const TDesC& aText, CEikLabel* aLabel ) + { + if ( aLabel ) + { + HBufC* localBuf = aText.AllocLC(); + TPtr ptr = localBuf->Des(); + AknTextUtils::DisplayTextLanguageSpecificNumberConversion( ptr ); + aLabel->SetTextL( ptr ); // Makes copy of buffer + CleanupStack::PopAndDestroy( localBuf ); + } + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::SetMinimumTextL +// Sets the text for the minimum label. +// ---------------------------------------------------------------------------- +// +EXPORT_C void CAknSlider::SetMinimumTextL( const TDesC& aText ) + { + DoSetLabelTextL( aText, iMinLabel ); + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::SetMaximumTextL +// Sets the text for the maximum label. +// ---------------------------------------------------------------------------- +// +EXPORT_C void CAknSlider::SetMaximumTextL( const TDesC& aText ) + { + DoSetLabelTextL( aText, iMaxLabel ); + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::MinimumSize +// ---------------------------------------------------------------------------- +// +TSize CAknSlider::MinimumSize() + { + TInt index = 0; + + if ( iEditable ) + { + if ( Layout() == EAknFormSliderLayout3 ) + { + index = 0; + } + else if ( Layout() == EAknFormSliderLayout2 ) + { + index = 1; + } + else if ( Layout() == EAknFormSliderLayout1 ) + { + index = 2; + } + } + + TAknLayoutRect temp, layout; + temp.LayoutRect( TRect( 0, 0, 0, 0 ), + AknLayoutScalable_Avkon::Screen() ); + + layout.LayoutRect( temp.Rect(), + AknLayoutScalable_Avkon::listscroll_form_pane() ); + temp.LayoutRect( layout.Rect(), + AknLayoutScalable_Avkon::list_form_gen_pane() ); + layout.LayoutRect( temp.Rect(), + AknLayoutScalable_Avkon::form_field_slider_pane( index ) ); + + return layout.Rect().Size(); + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::OfferKeyEventL +// Handles the key events. +// ---------------------------------------------------------------------------- +// +TKeyResponse CAknSlider::OfferKeyEventL( + const TKeyEvent& aKeyEvent, TEventCode aType ) + { + // If not a key event or in view mode + if ( aType != EEventKey || !iEditable ) + { + return EKeyWasNotConsumed; + } + + TInt step = StepSize(); + TBool hor = iExt->IsFlagSet( CAknSliderExtension::EFlagHorizontal ); + iExt->iPenInputPos = TPoint( -1, -1 ); + + if ( EKeyLeftArrow == aKeyEvent.iCode && hor ) + { + TranslateValueL( -step ); + } + else if ( EKeyRightArrow == aKeyEvent.iCode && hor ) + { + TranslateValueL( step ); + } + else if ( EKeyDownArrow == aKeyEvent.iCode && !hor ) + { + TranslateValueL( -step ); + } + else if ( EKeyUpArrow == aKeyEvent.iCode && !hor ) + { + TranslateValueL( step ); + } + else + { + return EKeyWasNotConsumed; + } + + return EKeyWasConsumed; + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::ConstructFromResourceL +// ---------------------------------------------------------------------------- +// +EXPORT_C void CAknSlider::ConstructFromResourceL( TResourceReader& aReader ) + { + iData = CAknSliderData::NewL( aReader ); + ConstructL(); + + // Apply constraints on the read stepsize here + SetStepSize( StepSize() ); + + // Set the labels up + if ( SliderData()->iMinimumLabelText ) + { + SetMinimumTextL( *( SliderData()->iMinimumLabelText ) ); + } + + if ( SliderData()->iMaximumLabelText ) + { + SetMaximumTextL( *( SliderData()->iMaximumLabelText ) ); + } + + // Create graphics if needed + if ( Layout() == EAknSettingsItemSliderLayoutWithGraphics ) + { + CreateDecoratorImageFromResourceL( SliderData()->iDecoratorImageId ); + } + + TAknLayoutRect layoutRect; + TRect containerRect; + if( Layout() == EAknSliderLayoutVertical ) + { + AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EApplicationWindow, + containerRect ); + + layoutRect.LayoutRect(containerRect,AknLayoutScalable_Avkon::main_pane(13) ); + containerRect = layoutRect.Rect(); + + layoutRect.LayoutRect( containerRect, + AknLayoutScalable_Avkon::popup_slider_window(0) ); + containerRect = layoutRect.Rect(); + + SetRect( containerRect ); + } + else if( Layout() == EAknSliderLayoutHorizontal ) + { + AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EApplicationWindow, + containerRect ); + + layoutRect.LayoutRect(containerRect,AknLayoutScalable_Apps::main_pane(0) ); + containerRect = layoutRect.Rect(); + + layoutRect.LayoutRect( containerRect, + AknLayoutScalable_Apps::main_video_tele_pane(0) ); + containerRect = layoutRect.Rect(); + + layoutRect.LayoutRect( containerRect, + AknLayoutScalable_Apps::popup_vtel_slider_window(0) ); + containerRect = layoutRect.Rect(); + + SetRect( containerRect ); + } + else + { + SetRect( MinimumSize() ); + } + + + SetValueTextL(); + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::ConstructFromResourceL +// ---------------------------------------------------------------------------- +// +EXPORT_C void CAknSlider::ConstructFromResourceL( + CCoeControl* aParent, TInt aValue, TResourceReader& aReader ) + { + SetContainerWindowL( *aParent ); + ConstructFromResourceL( aReader ); // Call basic ConstructFromResourceL() + SetValueL( aValue ); + ActivateL(); + //DrawNow(); + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::HandleResourceChange +// ---------------------------------------------------------------------------- +// +EXPORT_C void CAknSlider::HandleResourceChange( TInt aType ) + { + CCoeControl::HandleResourceChange( aType ); + + switch ( aType ) + { + case KEikMessageCaptionedControlEditableStateChange: + { + iEditable = ETrue; + MTouchFeedback* feedback = MTouchFeedback::Instance(); + if ( feedback ) + { + feedback->EnableFeedbackForControl( this, ETrue ); + } + } + break; + case KEikMessageCaptionedControlNotEditableStateChange: + { + iEditable = EFalse; + MTouchFeedback* feedback = MTouchFeedback::Instance(); + if ( feedback ) + { + feedback->EnableFeedbackForControl( this, EFalse ); + } + } + break; + + case KAknsMessageSkinChange: + { + SetLabelColor(); + } + break; + default: + break; + } + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::CountComponentControls +// Standard CCoeControl routine to return the number of component controls. +// ---------------------------------------------------------------------------- +// +EXPORT_C TInt CAknSlider::CountComponentControls() const + { + TInt count = 0; + CCoeControl* controls[] = { iValueLabel, iMaxLabel, iMinLabel, iImage }; + for ( TUint ii = 0; ii < sizeof( controls ) / sizeof( CCoeControl* ); ++ii ) + { + if ( controls[ii] ) + { + count++; + } + } + return count; + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::ComponentControl +// Standard CCoeControl routine to return the control at a given index +// ---------------------------------------------------------------------------- +// +EXPORT_C CCoeControl* CAknSlider::ComponentControl( TInt aIndex ) const + { + CCoeControl* controls[] = { iValueLabel, iMaxLabel, iMinLabel, iImage }; + for ( TUint ii = 0; ii < sizeof( controls ) / sizeof( CCoeControl* ); ++ii ) + { + if ( controls[ii] && aIndex-- == 0 ) + { + return controls[ii]; + } + } + return NULL; + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::SizeChanged +// Sets the layout. +// ---------------------------------------------------------------------------- +// +void CAknSlider::SizeChanged() + { + switch ( Layout() ) + { + case EAknFormSliderLayout1: + { + FormSliderLayout1(); + break; + } + case EAknFormSliderLayout2: + { + FormSliderLayout2(); + break; + } + case EAknFormSliderLayout3: + { + FormSliderLayout3(); + break; + } + case EAknSettingsItemSliderLayout: + case EAknSettingsItemSliderLayoutWithGraphics: + + { + SettingsItemSliderLayout(); + break; + } + case EAknMIDPFormSliderLayout: + { + MIDPFormSliderLayout(); + break; + } + case EAknSliderLayoutVertical: + { + VerticalSliderLayout(); + break; + } + case EAknSliderLayoutHorizontal: + { + HorizontalSliderLayout(); + break; + } + + default: + break; + } + + TAknLayoutRect horLine; + + if ( Layout() == EAknSettingsItemSliderLayout || + Layout() == EAknSettingsItemSliderLayoutWithGraphics || + Layout() == EAknSliderLayoutVertical || + Layout() == EAknSliderLayoutHorizontal ) + { + horLine.LayoutRect( iMarkerArea, + AKN_LAYOUT_WINDOW_Slider_pane_elements_Line_1 ); + } + else + { + horLine.LayoutRect( iMarkerArea, + AKN_LAYOUT_WINDOW_Slider_pane_elements__form__Line_1 ); + } + + TRect horRect = horLine.Rect(); + iColor = horLine.Color(); + + SetLabelColor(); + AknsUtils::RegisterControlPosition( this ); + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::FormSliderLayout1 +// Pure layout function. Value label is shown in the same place in View and +// Edit modes. +// ---------------------------------------------------------------------------- +// +void CAknSlider::FormSliderLayout1() + { + TRect rect = Rect(); + AknLayoutUtils::LayoutLabel( iValueLabel, rect, + AKN_LAYOUT_TEXT_Form_slider_field_texts_Line_2 ); + + TAknLayoutRect layoutRect; + + // slider_form_pane + TAknLayoutRect temp, layout; + temp.LayoutRect( rect, + AknLayoutScalable_Avkon::slider_cont_pane( 2 ) ); + + layout.LayoutRect( temp.Rect(), + AknLayoutScalable_Avkon::slider_form_pane( 1 ) ); + iMarkerArea = layout.Rect(); + + // Load new slider layout if exist + if( !(iExt->UsesDefaultGraphics()) ) + { + temp.LayoutRect( layout.Rect(), + AknLayoutScalable_Avkon::slider_form_pane_g4() ); + iLineRect = temp.Rect(); + + temp.LayoutRect( layout.Rect(), + AknLayoutScalable_Avkon::slider_form_pane_g3() ); + iExt->iLeftCapRect = temp.Rect(); + + temp.LayoutRect( layout.Rect(), + AknLayoutScalable_Avkon::slider_form_pane_g5() ); + iExt->iRightCapRect = temp.Rect(); + + temp.LayoutRect( layout.Rect(), + AknLayoutScalable_Avkon::slider_form_pane_g7() ); + iExt->iTickRect = temp.Rect(); + + temp.LayoutRect( layout.Rect(), + AknLayoutScalable_Avkon::slider_form_pane_g6() ); + iExt->iThumbRect = temp.Rect(); + + } + else + { + temp.LayoutRect( layout.Rect(), + AknLayoutScalable_Avkon::slider_form_pane_g1() ); + AknIconUtils::SetSize( iExt->iLineIcon, temp.Rect().Size() ); + iLineRect = temp.Rect(); + + temp.LayoutRect( layout.Rect(), + AknLayoutScalable_Avkon::slider_form_pane_g2() ); + iExt->iThumbRect = temp.Rect(); + } + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::FormSliderLayout2 +// Pure layout function. Value label is not shown in the same place in Edit +// mode. +// ---------------------------------------------------------------------------- +// +void CAknSlider::FormSliderLayout2() + { + TRect rect = Rect(); + if ( iEditable ) + { + AknLayoutUtils::LayoutLabel( iMinLabel, rect, + AKN_LAYOUT_TEXT_Form_slider_field_texts_Line_3( 0, 0 ) ); + AknLayoutUtils::LayoutLabel( iMaxLabel, rect, + AKN_LAYOUT_TEXT_Form_slider_field_texts_Line_3( 2, 2 ) ); + + TAknLayoutRect temp, layout; + temp.LayoutRect( rect, + AknLayoutScalable_Avkon::slider_cont_pane( 1 ) ); + + layout.LayoutRect( temp.Rect(), + AknLayoutScalable_Avkon::slider_form_pane( 0 ) ); + iMarkerArea = layout.Rect(); + //Load new slider layout if exist + if( !(iExt->UsesDefaultGraphics() ) ) + { + temp.LayoutRect( layout.Rect(), + AknLayoutScalable_Avkon::slider_form_pane_g4() ); + iLineRect = temp.Rect(); + + temp.LayoutRect( layout.Rect(), + AknLayoutScalable_Avkon::slider_form_pane_g3() ); + iExt->iLeftCapRect = temp.Rect(); + + temp.LayoutRect( layout.Rect(), + AknLayoutScalable_Avkon::slider_form_pane_g5() ); + iExt->iRightCapRect = temp.Rect(); + + temp.LayoutRect( layout.Rect(), + AknLayoutScalable_Avkon::slider_form_pane_g7() ); + iExt->iTickRect = temp.Rect(); + + temp.LayoutRect( layout.Rect(), + AknLayoutScalable_Avkon::slider_form_pane_g6() ); + iExt->iThumbRect = temp.Rect(); + } + else + { + temp.LayoutRect( layout.Rect(), + AknLayoutScalable_Avkon::slider_form_pane_g1() ); + AknIconUtils::SetSize( iExt->iLineIcon, temp.Rect().Size() ); + iLineRect = temp.Rect(); + + temp.LayoutRect( layout.Rect(), + AknLayoutScalable_Avkon::slider_form_pane_g2() ); + iExt->iThumbRect = temp.Rect(); + } + + if ( iValueLabel ) + { + // Label must not overlap control but width is used to set view + // mode text + TSize tempSize = iValueLabel->Size(); + iValueLabel->SetSize( TSize( tempSize.iWidth, 0 ) ); + } + } + else + { + AknLayoutUtils::LayoutLabel( iValueLabel, rect, + AKN_LAYOUT_TEXT_Form_slider_field_texts_Line_2 ); + } + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::FormSliderLayout3 +// Pure layout function. Value label is not shown in the same place in Edit +// mode. +// ---------------------------------------------------------------------------- +// +void CAknSlider::FormSliderLayout3() + { + TRect rect = Rect(); + + if ( iEditable ) + { + AknLayoutUtils::LayoutLabel( iValueLabel, rect, + AKN_LAYOUT_TEXT_Form_slider_field_texts_Line_2 ); + AknLayoutUtils::LayoutLabel( iMinLabel, rect, + AKN_LAYOUT_TEXT_Form_slider_field_texts_Line_3( 0, 1 ) ); + AknLayoutUtils::LayoutLabel( iMaxLabel, rect, + AKN_LAYOUT_TEXT_Form_slider_field_texts_Line_3( 2, 3 ) ); + + TAknLayoutRect temp, layout; + temp.LayoutRect( rect, + AknLayoutScalable_Avkon::slider_cont_pane( 0 ) ); + + // slider layout with value, min and max labels + layout.LayoutRect( temp.Rect(), + AknLayoutScalable_Avkon::slider_form_pane( 0 ) ); + iMarkerArea = layout.Rect(); + //Load new slider layout if exist + if( !(iExt->UsesDefaultGraphics()) ) + { + temp.LayoutRect( layout.Rect(), + AknLayoutScalable_Avkon::slider_form_pane_g4() ); + iLineRect = temp.Rect(); + + temp.LayoutRect( layout.Rect(), + AknLayoutScalable_Avkon::slider_form_pane_g3() ); + iExt->iLeftCapRect = temp.Rect(); + + temp.LayoutRect( layout.Rect(), + AknLayoutScalable_Avkon::slider_form_pane_g5() ); + iExt->iRightCapRect = temp.Rect(); + + temp.LayoutRect( layout.Rect(), + AknLayoutScalable_Avkon::slider_form_pane_g7() ); + iExt->iTickRect = temp.Rect(); + + temp.LayoutRect( layout.Rect(), + AknLayoutScalable_Avkon::slider_form_pane_g6() ); + iExt->iThumbRect = temp.Rect(); + } + else + { + temp.LayoutRect( layout.Rect(), + AknLayoutScalable_Avkon::slider_form_pane_g1() ); + AknIconUtils::SetSize( iExt->iLineIcon, temp.Rect().Size() ); + iLineRect = temp.Rect(); + + temp.LayoutRect( layout.Rect(), + AknLayoutScalable_Avkon::slider_form_pane_g2() ); + iExt->iThumbRect = temp.Rect(); + } + } + else + { + AknLayoutUtils::LayoutLabel( iValueLabel, rect, + AKN_LAYOUT_TEXT_Form_slider_field_texts_Line_2 ); + } + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::SettingsItemSliderLayout +// Pure layout function. +// ---------------------------------------------------------------------------- +// +void CAknSlider::SettingsItemSliderLayout() + { + TRect rect = Rect(); + iEditable = ETrue; + + TAknLayoutRect temp, layoutRect; + if ( Layout() == EAknSettingsItemSliderLayout) + + { + AknLayoutUtils::LayoutLabel( iValueLabel, rect, + AknLayoutScalable_Avkon::setting_slider_pane_t1_copy1( 0 ) ); + AknLayoutUtils::LayoutLabel( iMinLabel, rect, + AknLayoutScalable_Avkon::setting_slider_pane_t2_copy1( 0 ) ); + AknLayoutUtils::LayoutLabel( iMaxLabel, rect, + AknLayoutScalable_Avkon::setting_slider_pane_t3_copy1( 0 ) ); + layoutRect.LayoutRect( rect, + AknLayoutScalable_Avkon::slider_set_pane_copy1( 0 ) ); + // Indication rect for setting slider pane + iExt->iTouchDownArea = Rect(); + + iExt->iTouchActiveArea = TouchActiveArea(); + } + + if ( Layout() == EAknSettingsItemSliderLayoutWithGraphics ) + { + AknLayoutUtils::LayoutLabel( iMinLabel, rect, + AknLayoutScalable_Avkon::setting_slider_graphic_pane_t1_copy1( 0 ) ); + AknLayoutUtils::LayoutLabel( iMaxLabel, rect, + AknLayoutScalable_Avkon::setting_slider_graphic_pane_t2_copy1( 0 ) ); + AknLayoutUtils::LayoutImage( iImage, rect, + AknLayoutScalable_Avkon::setting_slider_graphic_pane_g1_copy1( 0 ) ); + AknIconUtils::SetSize( const_cast( iImage->Bitmap() ), + iImage->Size(), EAspectRatioNotPreserved ); + layoutRect.LayoutRect( rect, + AknLayoutScalable_Avkon::slider_set_pane_cp_copy1( 0 ) ); + // Indication rect for setting slider pane + iExt->iTouchDownArea = Rect(); + + iExt->iTouchActiveArea = TouchActiveArea(); + } + + iMarkerArea = layoutRect.Rect(); + + //new horizonal slider + if( !(iExt->UsesDefaultGraphics())) + { + temp.LayoutRect( iMarkerArea, + AknLayoutScalable_Avkon::slider_set_pane_g4_copy1(0) ); + iLineRect = temp.Rect(); + temp.LayoutRect( iMarkerArea, + AknLayoutScalable_Avkon::slider_set_pane_g3_copy1(0) ); + iExt->iLeftCapRect = temp.Rect(); + temp.LayoutRect( iMarkerArea, + AknLayoutScalable_Avkon::slider_set_pane_g5_copy1(0) ); + iExt->iRightCapRect = temp.Rect(); + temp.LayoutRect( iMarkerArea, + AknLayoutScalable_Avkon::slider_set_pane_g7_copy1(0) ); + iExt->iTickRect = temp.Rect(); + temp.LayoutRect( iMarkerArea, + AknLayoutScalable_Avkon::slider_set_pane_g6_copy1(0) ); + iExt->iThumbRect = temp.Rect(); + } + else //default slider + { + temp.LayoutRect( iMarkerArea, + AknLayoutScalable_Avkon::slider_set_pane_g1_copy1() ); + AknIconUtils::SetSize( iExt->iLineIcon, temp.Rect().Size() ); + iLineRect = temp.Rect(); + temp.LayoutRect( iMarkerArea, + AknLayoutScalable_Avkon::slider_set_pane_g2_copy1() ); + iExt->iThumbRect = temp.Rect(); + } + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::VerticalSliderLayout +// Pure layout function. +// ---------------------------------------------------------------------------- +// +void CAknSlider::VerticalSliderLayout() + { + TRect rect = Rect(); + iEditable = ETrue; + + TAknLayoutRect temp, layoutRect; + if( !(iExt->UsesDefaultGraphics())) + { + iMarkerArea = rect; + temp.LayoutRect( iMarkerArea, + AknLayoutScalable_Avkon::small_volume_slider_vertical_pane_g2() ); + iLineRect = temp.Rect(); + + temp.LayoutRect( iMarkerArea, + AknLayoutScalable_Avkon::small_volume_slider_vertical_pane_g3() ); + iExt->iThumbRect = temp.Rect(); + } + else + { + AknLayoutUtils::LayoutLabel( iValueLabel, rect, + AknLayoutScalable_Avkon::setting_slider_pane_t1(1) ); + AknLayoutUtils::LayoutLabel( iMinLabel, rect, + AknLayoutScalable_Avkon::setting_slider_pane_t2(1) ); + AknLayoutUtils::LayoutLabel( iMaxLabel, rect, + AknLayoutScalable_Avkon::setting_slider_pane_t3(1) ); + + iMarkerArea = rect; + //new vertical slider + + temp.LayoutRect( iMarkerArea, + AknLayoutScalable_Avkon::slider_pane_g3(0) ); + iLineRect = temp.Rect(); + + temp.LayoutRect( iMarkerArea, + AknLayoutScalable_Avkon::slider_pane_g1(0) ); + iExt->iLeftCapRect = temp.Rect(); + + temp.LayoutRect( iMarkerArea, + AknLayoutScalable_Avkon::slider_pane_g2(0) ); + iExt->iRightCapRect = temp.Rect(); + + temp.LayoutRect( iMarkerArea, + AknLayoutScalable_Avkon::slider_pane_g3(0) ); + iExt->iTickRect = temp.Rect(); + + temp.LayoutRect( iMarkerArea, + AknLayoutScalable_Avkon::slider_pane_g4(0) ); + iExt->iThumbRect = temp.Rect(); + } + } +// ---------------------------------------------------------------------------- +// CAknSlider::HorizontalSliderLayout +// Pure layout function. +// ---------------------------------------------------------------------------- +// +void CAknSlider::HorizontalSliderLayout() + { + TRect rect = Rect(); + iEditable = ETrue; + + TAknLayoutRect temp, layoutRect; + if( !( iExt->UsesDefaultGraphics() ) ) + { + iMarkerArea = rect; + temp.LayoutRect( iMarkerArea, + AknLayoutScalable_Apps::vtel_slider_pane_g2(0) ); + AknIconUtils::SetSize( iExt->iLineIcon, rect.Size() ); + iLineRect = Rect(); + + /*temp.LayoutRect( iMarkerArea, + AknLayoutScalable_Apps::vtel_slider_pane_g4(0) ); + iExt->iLeftCapRect = temp.Rect(); + + temp.LayoutRect( iMarkerArea, + AknLayoutScalable_Apps::vtel_slider_pane_g3(0) ); + iExt->iRightCapRect = temp.Rect();*/ + + temp.LayoutRect( rect, + AknLayoutScalable_Apps::vtel_slider_pane_g5(0) ); + iExt->iThumbRect = temp.Rect(); + } + else + { + AknLayoutUtils::LayoutLabel( iValueLabel, rect, + AknLayoutScalable_Avkon::setting_slider_pane_t1(0) ); + AknLayoutUtils::LayoutLabel( iMinLabel, rect, + AknLayoutScalable_Avkon::setting_slider_pane_t2(0) ); + AknLayoutUtils::LayoutLabel( iMaxLabel, rect, + AknLayoutScalable_Avkon::setting_slider_pane_t3(0) ); + layoutRect.LayoutRect( rect, + AknLayoutScalable_Avkon::slider_set_pane(0) ); + + iMarkerArea = layoutRect.Rect(); + //new vertical slider + + temp.LayoutRect( iMarkerArea, + AknLayoutScalable_Avkon::slider_set_pane_g4(0) ); + iLineRect = temp.Rect(); + + temp.LayoutRect( iMarkerArea, + AknLayoutScalable_Avkon::slider_set_pane_g3(0) ); + iExt->iLeftCapRect = temp.Rect(); + + temp.LayoutRect( iMarkerArea, + AknLayoutScalable_Avkon::slider_set_pane_g5(0) ); + iExt->iRightCapRect = temp.Rect(); + + temp.LayoutRect( iMarkerArea, + AknLayoutScalable_Avkon::slider_set_pane_g7(0) ); + iExt->iTickRect = temp.Rect(); + + temp.LayoutRect( iMarkerArea, + AknLayoutScalable_Avkon::slider_set_pane_g6(0) ); + iExt->iThumbRect = temp.Rect(); + } + } +// ---------------------------------------------------------------------------- +// CAknSlider::MIDPFormSliderLayout +// Pure layout function. Value, min and max labels are shown. +// ---------------------------------------------------------------------------- +// +void CAknSlider::MIDPFormSliderLayout() + { + TRect rect = Rect(); + if ( iEditable ) + { + AknLayoutUtils::LayoutLabel( iValueLabel, rect, + AknLayoutScalable_Avkon::form2_midp_gauge_slider_pane_t1() ); + + TAknLayoutRect layout, temp; + layout.LayoutRect( rect, + AknLayoutScalable_Avkon::form2_midp_gauge_slider_cont_pane(0) ); + AknLayoutUtils::LayoutLabel( iMinLabel, layout.Rect(), + AknLayoutScalable_Avkon::form2_midp_gauge_slider_pane_t2_cp01(0) ); + AknLayoutUtils::LayoutLabel( iMaxLabel, layout.Rect(), + AknLayoutScalable_Avkon::form2_midp_gauge_slider_pane_t3_cp01(1) ); + temp.LayoutRect( layout.Rect(), + AknLayoutScalable_Avkon::form2_midp_slider_pane_cp01(0)); + iMarkerArea = temp.Rect(); + temp.LayoutRect( iMarkerArea, + AknLayoutScalable_Avkon::form2_midp_slider_pane_g2(0) ); + AknIconUtils::SetSize( iExt->iLineIcon, temp.Rect().Size() ); + iLineRect = temp.Rect(); + + temp.LayoutRect( iMarkerArea, + AknLayoutScalable_Avkon::form2_midp_slider_pane_g1(0) ); + iExt->iLeftCapRect = temp.Rect(); + + temp.LayoutRect( iMarkerArea, + AknLayoutScalable_Avkon::form2_midp_slider_pane_g3(0) ); + iExt->iRightCapRect = temp.Rect(); + + temp.LayoutRect( iMarkerArea, + AknLayoutScalable_Avkon::slider_form_pane_g7(0) ); + iExt->iTickRect = temp.Rect(); + + temp.LayoutRect( iMarkerArea, + AknLayoutScalable_Avkon::slider_form_pane_g2() ); + iExt->iThumbRect = temp.Rect(); + } + else + { + AknLayoutUtils::LayoutLabel( iValueLabel, rect, + AKN_LAYOUT_TEXT_Form_slider_field_texts_Line_2 ); + } + } + +// ---------------------------------------------------------------------------- +// CAknSlider::Draw +// Implementation of automatically called control drawing function from +// CCoeControl. +// ---------------------------------------------------------------------------- +// +void CAknSlider::Draw( const TRect& /*aRect*/ ) const + { + if ( iExt->IsFlagSet( CAknSliderExtension::EFlagHorizontal ) ) + { + DrawHorizontal( ETrue ); + } + else // must be vertical + { + DrawVertical( ETrue ); + } + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::DrawHorizontalTickMarks +// +// Draws horizontal tick marks. The slider grows rightwards and tick marks are +// placed above or below the line. If tick mark interval is zero the repeat +// step size is used as the interval. +// +// Slider range is not a pixel space, conversion must be done from +// slider range to actual pixel range. Using one pixel width for the +// tick interval in pixel space is not possible, as rounding errors +// would cumulate. Each tick pixel coordinate must be separately +// determined. +// +// Slider range [r1, r2] e Z, pixel range [p1, p2] e Z. Mapping from +// slider range position r to pixel range position p: +// +// | (r - r1)(p2 - p1) | +// p = p1 + | ----------------- | +// |_ r2 - r1 _| +// +// Flooring indicates truncation caused by integer division. +// ---------------------------------------------------------------------------- +// +void CAknSlider::DrawHorizontalTickMarks( CWindowGc& aGc ) const + { + TAknSliderGfx gfx; + FetchGfx( gfx, EElemTickMark, iExt->iTickRect.Size() ); + + if ( !gfx.iRgb ) + { + aGc.SetBrushStyle( CWindowGc::ESolidBrush ); + aGc.SetBrushColor( AKN_LAF_COLOR( KAknSliderDefaultDrawColor ) ); + } + + const TInt mw = MarkerSize().iWidth; // Marker width + const TInt r1 = SliderData()->iMinimumValue; // Slider range start + const TInt r2 = SliderData()->iMaximumValue; // Slider range end + // Note that r2 - r1 > 0 as slider quarantees that + // SliderData()->iMinimumValue < SliderData()->iMaximumValue. + + const TInt p1 = iMarkerArea.iTl.iX + mw / 2; // Pixel range start + const TInt p2 = p1 + iMarkerArea.Width() - mw; // Pixel range end + + // Interval between tick marks, if zero then use step spacing. + // StepSize is always >= 1, therefore s cannot be zero which would + // lead to infinite loop below. + const TInt s = ( 0 == iExt->iTickInterval ) ? StepSize(): + iExt->iTickInterval; + + const TInt tickWidth = iExt->iTickRect.Size().iWidth; + + // If tick width is even, handle as if it was uneven. The extra column of + // pixels is aligned to right side of the tick mark middle position. + const TInt off = ( tickWidth / 2 ) - + ( ( tickWidth % 2 == 0 ) ? 1: 0 ); + + + TRect rect = iExt->iTickRect; + + for ( int r = r1; r <= r2; r += s ) + { + // Current pos in the range -> current pos on screen, r2 - r1 > 0 + // always (see comment above). + rect.iTl.iX = p1 + ( ( r - r1 ) * ( p2 - p1 ) ) / ( r2 - r1 ) - off; + rect.iBr.iX = rect.iTl.iX + tickWidth; + + if ( gfx.iRgb && gfx.iMask ) + { + aGc.BitBltMasked( rect.iTl, gfx.iRgb, rect.Size(), gfx.iMask, EFalse ); + } + else if ( gfx.iRgb ) + { + aGc.BitBlt( rect.iTl, gfx.iRgb, rect.Size() ); + } + else + { + aGc.DrawRect( rect ); + } + } + aGc.SetBrushStyle( CGraphicsContext::ENullBrush ); + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::DrawVerticalTickMarks +// +// Draws vertical tick marks. The slider grows upwards and tick marks are +// placed to the left or right of the line. If tick mark interval is zero the +// repeat step size is used as the interval. Implementation is similar to +// DrawHorizontalTickMarks, the major difference is that in vertical mode +// slider range and pixel range grow to different directions. +// ---------------------------------------------------------------------------- +// +void CAknSlider::DrawVerticalTickMarks( CWindowGc& aGc ) const + { + TAknSliderGfx gfx; + FetchGfx( gfx, EElemTickMark, iExt->iTickRect.Size() ); + + if ( !gfx.iRgb ) + { + aGc.SetBrushStyle( CWindowGc::ESolidBrush ); + aGc.SetBrushColor( AKN_LAF_COLOR( KAknSliderDefaultDrawColor ) ); + } + + const TInt mh = MarkerSize().iHeight; // Marker height + const TInt r1 = SliderData()->iMinimumValue; // Slider range start + const TInt r2 = SliderData()->iMaximumValue; // Slider range end + // Note that r2 - r1 > 0 as slider quarantees that + // SliderData()->iMinimumValue < SliderData()->iMaximumValue. + + const TInt p2 = iMarkerArea.iBr.iY - mh / 2; // Pixel range end + const TInt p1 = p2 - iMarkerArea.Height() + mh; // Pixel range start + + // Interval between tick marks, if zero then use step spacing. + // StepSize is always >= 1, therefore s cannot be zero which would + // lead to infinite loop below. + const TInt s = ( 0 == iExt->iTickInterval ) ? StepSize(): + iExt->iTickInterval; + + const TInt tickHeight = iExt->iTickRect.Size().iHeight; + + // If tick width is even, handle as if it was uneven. The extra column of + // pixels is aligned above the tick mark middle position. + const TInt off = ( tickHeight / 2 ) - + ( ( tickHeight % 2 == 0 ) ? 1: 0 ); + + TRect rect = iExt->iTickRect; + for ( int r = r1; r <= r2; r += s ) + { + // Current pos in the range -> current pos on screen, r2 - r1 > 0, + // checked above + rect.iBr.iY = p2 - ( ( r - r1 ) * ( p2 - p1 ) ) / ( r2 - r1 ) + off; + rect.iTl.iY = rect.iBr.iY - tickHeight; + + if ( gfx.iRgb && gfx.iMask ) + { + aGc.BitBltMasked( rect.iTl, gfx.iRgb, rect.Size(), gfx.iMask, EFalse ); + } + else if ( gfx.iRgb ) + { + aGc.BitBlt( rect.iTl, gfx.iRgb, rect.Size() ); + } + else + { + aGc.DrawRect( rect ); + } + } + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::CreateDecoratorImageFromResourceL +// ---------------------------------------------------------------------------- +// +void CAknSlider::CreateDecoratorImageFromResourceL( TInt aImageResourceId ) + { + iImage = new ( ELeave ) CEikImage(); + TResourceReader reader; + CEikonEnv::Static()->CreateResourceReaderLC( reader, aImageResourceId ); + iImage->ConstructFromResourceL( reader ); + CleanupStack::PopAndDestroy(); // reader + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::SetDecimalPlaces +// ---------------------------------------------------------------------------- +// +EXPORT_C void CAknSlider::SetDecimalPlaces( TInt aDecimalPlaces ) + { + SliderData()->SetDecimalPlaces( aDecimalPlaces ); + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::DecimalPlaces +// ---------------------------------------------------------------------------- +// +EXPORT_C TInt CAknSlider::DecimalPlaces() const + { + return SliderData()->DecimalPlaces(); + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::SetGraphics +// ---------------------------------------------------------------------------- +// +EXPORT_C void CAknSlider::SetGraphics( TInt aElement, CFbsBitmap* aBitmap, + CFbsBitmap* aMask ) + { + if ( aElement < 0 || aElement > EElemMarkerSelected )//|| !aBitmap ) + { + Panic( EAknPanicInvalidValue ); + } + + iExt->SetGraphics( aElement, aBitmap, aMask ); + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::UseDefaultGraphics +// ---------------------------------------------------------------------------- +// +EXPORT_C void CAknSlider::UseDefaultGraphics( TInt aElement ) + { + if ( aElement < 0 || aElement > EElemMarkerSelected ) + { + Panic( EAknPanicInvalidValue ); + } + + iExt->UseDefaultGraphics( aElement ); + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::UsesDefaultGraphics +// ---------------------------------------------------------------------------- +// +EXPORT_C TBool CAknSlider::UsesDefaultGraphics( TInt aElement ) const + { + if ( aElement < 0 || aElement > EElemMarkerSelected ) + { + Panic( EAknPanicInvalidValue ); + } + + return iExt->UsesDefaultGraphics( aElement ); + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::SetPositionIndicators +// ---------------------------------------------------------------------------- +// +EXPORT_C void CAknSlider::SetPositionIndicators( TUint32 aFlags ) + { + iExt->ClearFlag( CAknSliderExtension::EFlagFillEnabled ); + iExt->ClearFlag( CAknSliderExtension::EFlagMarkerEnabled ); + + if ( EPosFilling & aFlags ) + { + iExt->SetFlag( CAknSliderExtension::EFlagFillEnabled ); + } + else + { + // If no position indicator is set, always default to visible + // marker + iExt->SetFlag( CAknSliderExtension::EFlagMarkerEnabled ); + } + + if ( EPosMarker & aFlags ) + { + iExt->SetFlag( CAknSliderExtension::EFlagMarkerEnabled ); + } + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::PositionIndicators +// ---------------------------------------------------------------------------- +// +EXPORT_C TUint32 CAknSlider::PositionIndicators() const + { + TUint32 flags = 0; + + if ( iExt->IsFlagSet( CAknSliderExtension::EFlagMarkerEnabled ) ) + { + flags |= EPosMarker; + } + + if ( iExt->IsFlagSet( CAknSliderExtension::EFlagFillEnabled ) ) + { + flags |= EPosFilling; + } + + return flags; + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::Orientation +// ---------------------------------------------------------------------------- +// +EXPORT_C TAknOrientation CAknSlider::Orientation() const + { + if ( iExt->IsFlagSet( CAknSliderExtension::EFlagHorizontal ) ) + { + return EAknOrientationHorizontal; + } + return EAknOrientationVertical; + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::SetTicksEnabled +// ---------------------------------------------------------------------------- +// +EXPORT_C void CAknSlider::SetTicksEnabled( TBool aStatus ) + { + if ( aStatus ) + { + iExt->SetFlag( CAknSliderExtension::EFlagTickMarksEnabled ); + } + else + { + iExt->ClearFlag( CAknSliderExtension::EFlagTickMarksEnabled ); + } + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::TicksEnabled +// ---------------------------------------------------------------------------- +// +EXPORT_C TBool CAknSlider::TicksEnabled() const + { + return iExt->IsFlagSet( CAknSliderExtension::EFlagTickMarksEnabled ); + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::SetTickInterval +// ---------------------------------------------------------------------------- +// +EXPORT_C void CAknSlider::SetTickInterval( TUint aInterval ) + { + iExt->iTickInterval = aInterval; + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::TickInterval +// ---------------------------------------------------------------------------- +// +EXPORT_C TUint CAknSlider::TickInterval() const + { + return iExt->iTickInterval; + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::NumberOfLines +// ---------------------------------------------------------------------------- +// +EXPORT_C TInt CAknSlider::NumberOfLines() const + { + TInt noOfLines = 1; + + if ( iEditable ) + { + switch ( Layout() ) + { + case EAknFormSliderLayout1: // drop through + case EAknFormSliderLayout2: + noOfLines = 2; + break; + case EAknFormSliderLayout3: + noOfLines = 3; + break; + default: + break; + } + } + + return noOfLines; + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::CreateValueTextInHBufCL +// +// Returns the text that would appear at the top of the slider setting page if +// it were opened Ownership of the text buffer is transferred to the caller. +// ---------------------------------------------------------------------------- +// +EXPORT_C HBufC* CAknSlider::CreateValueTextInHBufCL( + TInt aValue, TInt aResourceId ) + { + CAknSliderData* sliderResourceData = CAknSliderData::NewLC( aResourceId ); + + __ASSERT_DEBUG( aValue >= sliderResourceData->iMinimumValue && + aValue <= sliderResourceData->iMaximumValue, + Panic( EAknPanicOutOfRange ) ); + + TBuf textBuffer; + CAknSlider::DoSetValueTextL( textBuffer, aValue, *sliderResourceData ); + + CleanupStack::PopAndDestroy(); // sliderResourceData + HBufC* valueTextBufC = textBuffer.AllocL(); + return valueTextBufC; + } + +// ---------------------------------------------------------------------------- +// CAknSlider::StepSize +// ---------------------------------------------------------------------------- +// +TInt CAknSlider::StepSize() const + { + return iData->iStepSize; + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::Layout +// ---------------------------------------------------------------------------- +// +TInt CAknSlider::Layout() const + { + return iData->iLayout; + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::MaximumValue +// ---------------------------------------------------------------------------- +// +TInt CAknSlider::MaximumValue() const + { + return iData->iMaximumValue; + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::MinimumValue +// ---------------------------------------------------------------------------- +// +TInt CAknSlider::MinimumValue() const + { + return iData->iMinimumValue; + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::Range +// ---------------------------------------------------------------------------- +// +TInt CAknSlider::Range() const + { + return iData->Range(); + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::SliderData +// ---------------------------------------------------------------------------- +// +CAknSliderData* CAknSlider::SliderData() const + { + // This method is used to trap all the accesses to the internal data when + // the 2nd stage construction has not taken place + __ASSERT_DEBUG( iData, Panic( EAknPanicObjectNotFullyConstructed ) ); + return iData; + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::HandlePointerEventL +// +// Handles slider's pointer events. This function calculates thumb position +// when button down happens. Then it compares position to thumb position and if +// pointerevent was for the thumb it will set dragging on. Otherwise, the thumb +// will be moved to down position. +// +// If value have to be changed with this pointerevent, the new value have to be +// calculated. The calculation is based for drawing, so we have to find "what +// value" would be drawn to clicked position and thus deside what value was +// selected from slider. +// ---------------------------------------------------------------------------- +// +EXPORT_C void CAknSlider::HandlePointerEventL( const TPointerEvent& aEvent ) + { + if ( !AknLayoutUtils::PenEnabled() ) + { + return; + } + + if ( IsDimmed() ) + { + iExt->ClearFlag( CAknSliderExtension::EFlagPointerDown ); + iExt->ClearFlag( CAknSliderExtension::EFlagDraggingThumb ); + return; + } + + TBool thumbMoved = EFalse; + TBool valueChanged = EFalse; + TBool upFromDrag = EFalse; + TRect mrect; + GetMarkerRect( mrect ); + TInt reportDragEvent(0);// if this value is 0, it means no need to report + TBool hor = iExt->IsFlagSet( CAknSliderExtension::EFlagHorizontal ); + + //Setting pane slider use extended touch area to hand pointer event + TRect touchDownArea; + TRect touchActiveArea; + if( Layout() == EAknSettingsItemSliderLayout || + Layout() == EAknSettingsItemSliderLayoutWithGraphics + ) + { + touchDownArea = iExt->iTouchDownArea; + touchActiveArea = iExt->iTouchActiveArea; + } + else + { + touchDownArea = iMarkerArea; + touchActiveArea = iMarkerArea; + } + + if( iEditable ) + { + switch ( aEvent.iType ) + { + case TPointerEvent::EButton1Down: + { + if ( touchDownArea.Contains( aEvent.iPosition ) ) + { + // repeat until thumb reaches the stylus down position + iExt->iPenInputPos = aEvent.iPosition; + + // Click was inside and down slider marker area + iExt->SetFlag( CAknSliderExtension::EFlagPointerDown ); + // Start draggint even if the click was not inside thumb rect + if ( mrect.Contains( aEvent.iPosition ) ) + { + MTouchFeedback* feedback = MTouchFeedback::Instance(); + if ( feedback ) + { + feedback->InstantFeedback( this, ETouchFeedbackSlider, aEvent ); + } + iExt->SetFlag( CAknSliderExtension::EFlagDraggingThumb ); + reportDragEvent = EDragMarkerStart; + } + // Marker icon changes - draw + if ( !iExt->iNoDraw ) + { + DrawDeferred(); + } + valueChanged = ETrue; + } + } + break; + case TPointerEvent::EButtonRepeat: + { + if ( touchActiveArea.Contains( aEvent.iPosition ) ) + { + // repeat until thumb reaches the stylus down position + iExt->iPenInputPos = aEvent.iPosition; + + // Click was inside and down slider marker area + iExt->SetFlag( CAknSliderExtension::EFlagPointerDown ); + // Start draggint even if the click was not inside thumb rect + if ( mrect.Contains( aEvent.iPosition ) ) + { + iExt->SetFlag( CAknSliderExtension::EFlagDraggingThumb ); + reportDragEvent = EDragMarkerStart; + } + // Marker icon changes - draw + if ( !iExt->iNoDraw ) + { + DrawDeferred(); + } + valueChanged = ETrue; + } + if ( mrect.Contains( aEvent.iPosition ) ) + { + StopFeedback(); + } + } + break; + // Drag can out of touchDownArea to support finger touch out of range, + // when the pointer fall down the thumb,then use touchDragArea + case TPointerEvent::EDrag: + { + if ( ( iExt->IsFlagSet( CAknSliderExtension::EFlagDraggingThumb ) || + touchActiveArea.Contains( aEvent.iPosition ) ) && + iExt->IsFlagSet( CAknSliderExtension::EFlagPointerDown ) ) + { + if ( hor && aEvent.iPosition.iX != iExt->iPenInputPos.iX ) + { + thumbMoved = ETrue; + } + if ( !hor && aEvent.iPosition.iY != iExt->iPenInputPos.iY ) + { + thumbMoved = ETrue; + } + iExt->iPenInputPos = aEvent.iPosition; + valueChanged = ETrue; + } + if ( !iExt->IsFlagSet( CAknSliderExtension::EFlagDraggingThumb ) && + !touchActiveArea.Contains( aEvent.iPosition )) + { + StopFeedback(); + } + } + break; + + case TPointerEvent::EButton1Up: + { + if ( iExt->IsFlagSet( CAknSliderExtension::EFlagDraggingThumb ) && + iExt->IsFlagSet( CAknSliderExtension::EFlagPointerDown ) ) + { + iExt->iPenInputPos = aEvent.iPosition; + valueChanged = ETrue; + upFromDrag = ETrue; + reportDragEvent = EDragMarkerEnd; + } + iExt->ClearFlag( CAknSliderExtension::EFlagPointerDown ); + iExt->ClearFlag( CAknSliderExtension::EFlagDraggingThumb ); + if ( mrect.Contains( aEvent.iPosition ) ) + { + MTouchFeedback* feedback = MTouchFeedback::Instance(); + if ( feedback ) + { + feedback->InstantFeedback( this, + ETouchFeedbackSlider, + ETouchFeedbackVibra, + aEvent ); + } + } + StopFeedback(); + + // Marker icon changes - draw + if ( !iExt->iNoDraw ) + { + DrawDeferred(); + } + } + break; + + default: + break; + } + } + + + TBool valueStepChange = iExt->IsFlagSet( CAknSliderExtension::EFlagValueStepChange ); + + // if pointerevent causes value changing, we have to calculate the + // clicked value. + if ( valueChanged ) + { + TInt betweenSteps; + TInt value = Value(); + TBool isDragThumb = EFalse; + + if( (iExt->IsFlagSet( CAknSliderExtension::EFlagDraggingThumb ) && + iExt->IsFlagSet( CAknSliderExtension::EFlagPointerDown )) || + !valueStepChange || upFromDrag ) + { + //not value step or drag happened + isDragThumb = ETrue; + value = CalcAlignedValue( iExt->iPenInputPos ); + } + else if( !mrect.Contains( aEvent.iPosition ) ) + {// value step change begin + TInt step = StepSize(); + TInt halfStepRange(0); + TBool repeat = ( ( aEvent.iType == TPointerEvent::EButton1Down ) || + ( aEvent.iType == TPointerEvent::EButtonRepeat ) ) ? ETrue : EFalse; + + if(!hor) + { + halfStepRange = (iMarkerArea.Height() - mrect.Height())/( 2 * Range() ); + if( aEvent.iPosition.iY < mrect.iTl.iY + mrect.Height()/2 - halfStepRange ) + { + TranslateValueL( step, repeat ); + value = iValue; + } + else if( aEvent.iPosition.iY > mrect.iTl.iY + mrect.Height()/2 + halfStepRange ) + { + TranslateValueL( -step, repeat ); + value = iValue; + } + else + { + value = iValue; + } + } + else + { + halfStepRange = (iMarkerArea.Width() - mrect.Width())/( 2 * Range() ); + if( aEvent.iPosition.iX < mrect.iTl.iX + mrect.Width()/2 - halfStepRange ) + { + TranslateValueL( -step, repeat ); + value = iValue; + } + else if( aEvent.iPosition.iX > mrect.iTl.iX + mrect.Width()/2 + halfStepRange ) + { + TranslateValueL( step, repeat ); + value = iValue; + } + else + { + value = iValue; + } + } + + Window().RequestPointerRepeatEvent( KScrollRepeatTimeout, touchActiveArea ); + }// value step change over + + // calculate how many pixels was clicked between steps + betweenSteps = value % StepSize(); + + if ( betweenSteps != 0 ) + { + value = value - betweenSteps; + + // if click was nearer or middle of values, then move it to + // next possible value + if ( betweenSteps > ( StepSize() / 2 ) ) + { + value = value + StepSize(); + } + } + + // Move to Max/Min values if value is not withing range + if ( value > MaximumValue() ) + { + value = MaximumValue(); + } + else if ( value < MinimumValue() ) + { + value = MinimumValue(); + } + if( value == MinimumValue() ) + { + //The value is minimum value, but the pointer fell on the position which is + //less than minimum + 1 position. + if( hor && + aEvent.iPosition.iX < iMarkerArea.iTl.iX + iExt->iThumbRect.Width() / 2 + + ( iMarkerArea.iTl.iX - iExt->iThumbRect.Width() ) / Range() ) + { + iExt->iPenInputPos = + TPoint( iMarkerArea.iTl.iX + iExt->iThumbRect.Width() / 2, + iMarkerArea.iTl.iY ); + thumbMoved = EFalse; + } + + if( !hor && + aEvent.iPosition.iY > iMarkerArea.iBr.iY - iExt->iThumbRect.Height() / 2 - + ( iMarkerArea.iTl.iY - iExt->iThumbRect.Height() ) / Range() ) + { + iExt->iPenInputPos = + TPoint( iMarkerArea.iBr.iX, + iMarkerArea.iTl.iY - iExt->iThumbRect.Height() / 2 ); + thumbMoved = EFalse; + } + } + if( value == MaximumValue() ) + { + if( hor ) + { + iExt->iPenInputPos.iX = iMarkerArea.iTl.iX - iExt->iThumbRect.Width() / 2; + thumbMoved = EFalse; + } + else + { + iExt->iPenInputPos.iY = iMarkerArea.iTl.iY + iExt->iThumbRect.Height() / 2; + thumbMoved = EFalse; + } + } + if ( thumbMoved ) + { + StartFeedback( &aEvent, KFeedbackTimeout ); + } + if ( iValue != value ) + { + SetValueL( value ); + if ( &Window() != NULL ) + { + ReportEventL( MCoeControlObserver::EEventStateChanged ); + if ( !iExt->iNoDraw ) + { + DrawDeferred(); + } + } + } + else if( isDragThumb ) // fix TSW EAKH-7FAF63 + { + // smoothly + DrawDeferred(); + } + } + + // Report drag event if it is needed + if( iExt->iReportMarkerDragEvent && reportDragEvent ) + { + ReportEventL( static_cast(reportDragEvent) ); + } + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::CalcAlignedValue +// ---------------------------------------------------------------------------- +// +TInt CAknSlider::CalcAlignedValue( const TPoint& aPoint ) + { + TBool hor = iExt->IsFlagSet( CAknSliderExtension::EFlagHorizontal ); + TInt bitmapRun = 0; + TInt returnValue = MinimumValue(); + + if ( hor ) + { + bitmapRun = iMarkerArea.Width() - iExt->iThumbRect.Width(); + returnValue = ( ( Range() * ( aPoint.iX - iMarkerArea.iTl.iX - + iExt->iThumbRect.Width() / 2 ) + bitmapRun / 2 ) / bitmapRun ) + MinimumValue(); + } + else + { + bitmapRun = iMarkerArea.Height() - iExt->iThumbRect.Height(); + returnValue = ( ( Range() * ( iMarkerArea.iBr.iY - aPoint.iY - + iExt->iThumbRect.Height() / 2 ) + bitmapRun / 2 ) / bitmapRun ) + MinimumValue(); + } + return returnValue; + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::ExtensionInterface +// ---------------------------------------------------------------------------- +// +EXPORT_C void* CAknSlider::ExtensionInterface( TUid /*aInterface*/ ) + { + return NULL; + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::StartTimerL +// ---------------------------------------------------------------------------- +// +void CAknSlider::StartTimerL() + { + if ( iExt->iTimer->IsActive() ) + { + return; // do not re-start as we have the feedback ongoing + } + + iExt->iEffectTimerCount = 0; + + TCallBack callback( IndicationDrawCallbackL, this ); + iExt->iTimer->Start( + TTimeIntervalMicroSeconds32( KAknSliderFeedbackActionTime ), + KAknSliderFeedbackActionTime, callback ); + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::IndicationDrawCallbackL +// ---------------------------------------------------------------------------- +// +TInt CAknSlider::IndicationDrawCallbackL( TAny* aThis ) + { + CAknSlider* slider = static_cast( aThis ); + slider->SmallDirectionIndicationL(); + return KErrNone; + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::SmallDirectionIndicationL +// ---------------------------------------------------------------------------- +// +void CAknSlider::SmallDirectionIndicationL() + { + Window().Invalidate( iMarkerArea ); + ActivateGc(); + Window().BeginRedraw( iMarkerArea ); + CWindowGc& gc = SystemGc(); + gc.SetBrushStyle( CGraphicsContext::ENullBrush ); + gc.SetBrushColor( AKN_LAF_COLOR( 0 ) ); + gc.SetPenColor( AKN_LAF_COLOR( 0 ) ); + + if( !Background() ) + { + MAknsSkinInstance* skin = AknsUtils::SkinInstance(); + MAknsControlContext* cc = NULL; + if ( AknsUtils::AvkonSkinEnabled() ) + { + cc = AknsDrawUtils::ControlContext( this ); + } + AknsDrawUtils::Background( skin, cc, this, gc, Rect() ); + } + else + { + TRect rect = Window().GetDrawRect(); + Background()->Draw( gc, *this, rect ); + } + + TBool drawMarker = EFalse; + if ( iExt->iEffectTimerCount % 2 == 1 ) + { + drawMarker = ETrue; + } + + if ( iExt->IsFlagSet( CAknSliderExtension::EFlagHorizontal ) ) + { + DrawHorizontal( drawMarker ); + } + else // Must be vertical + { + DrawVertical( drawMarker ); + } + + Window().EndRedraw(); + DeactivateGc(); + + iExt->iEffectTimerCount++; + + // Stop timer if done normal-inverted-normal-inverted-normal sequence + if ( iExt->iEffectTimerCount > 3 ) + { + iExt->iTimer->Cancel(); + } + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::TranslateValueL +// +// Moves the current slider value by aDelta. If the value of aDelta is +// negative, the current value is decremented by |aDelta|. If the value of +// aDelta is positive, the current value is incremented by |aDelta|. +// ---------------------------------------------------------------------------- +// +void CAknSlider::TranslateValueL( TInt aDelta, TBool aFeedback ) + { + TInt sliderValue = Value(); + + sliderValue += aDelta; + + // calculate how many pixels was clicked between steps + TInt betweenSteps = sliderValue % StepSize(); + + if ( betweenSteps != 0 ) + { + sliderValue = sliderValue - betweenSteps; + + // if click was nearer or middle of values, then move it to + // next possible value + if ( betweenSteps > ( StepSize() / 2 ) ) + { + sliderValue = sliderValue + StepSize(); + } + } + + if ( sliderValue > MaximumValue() ) + { + sliderValue = MaximumValue(); + } + else if ( sliderValue < MinimumValue() ) + { + sliderValue = MinimumValue(); + } + + + TInt oldSliderValue = Value(); + SetValueL( sliderValue ); + + ReportEventL( MCoeControlObserver::EEventStateChanged ); + + // start the timer if we tried to move the slider but the slider did + // not move (in either maximum or minimum already). +#ifdef RD_ANIMATION_EFFECTS + if ( sliderValue == oldSliderValue ) + { + StartTimerL(); + } +#endif + + if ( sliderValue != oldSliderValue ) + { + if( aFeedback ) + { + MTouchFeedback* feedback = MTouchFeedback::Instance(); + if ( feedback ) + { + feedback->InstantFeedback( this, ETouchFeedbackSlider ); + } + } + + Window().Invalidate( Rect() ); + } + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::GetMarkerRect +// +// Returns the marker rectangle (the knob). Note that this is not equal to +// iMarkerArea. +// ---------------------------------------------------------------------------- +// +void CAknSlider::GetMarkerRect( TRect& aRect ) const + { + aRect = TRect( MarkerPos(), MarkerSize()); + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::MarkerSize +// +// Returns the marker size (the knob). Note that this is not equal to +// iMarkerArea.Size(). +// ---------------------------------------------------------------------------- +// +TSize CAknSlider::MarkerSize() const + { + return iExt->iThumbRect.Size(); + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::MarkerPos +// +// Returns the marker position (knob). Note that this is not equal to +// iMarkerArea.iTl. +// ---------------------------------------------------------------------------- +// +TPoint CAknSlider::MarkerPos() const + { + TPoint p; + + if ( iExt->IsFlagSet( CAknSliderExtension::EFlagHorizontal ) ) + { + TSize markerSize( MarkerSize() ); + TInt pixelRange = iMarkerArea.Width() - markerSize.iWidth; + TInt pos = ( pixelRange * ( iValue - MinimumValue() ) / Range() ); + + if ( AknLayoutUtils::PenEnabled() && + iMarkerArea.Contains( iExt->iPenInputPos ) && + &Window() != NULL ) + { + if( !iExt->IsFlagSet( CAknSliderExtension::EFlagValueStepChange ) || + ( iExt->IsFlagSet( CAknSliderExtension::EFlagDraggingThumb ) && + iExt->IsFlagSet( CAknSliderExtension::EFlagPointerDown ) ) ) + { + p.iX = iExt->iPenInputPos.iX - ( markerSize.iWidth ) / 2; + } + else + { + p.iX = iMarkerArea.iTl.iX + pos; + } + } + else + { + p.iX = iMarkerArea.iTl.iX + pos; + } + p.iY = iMarkerArea.iTl.iY; + } + else + { + TSize markerSize( MarkerSize() ); + TInt pixelRange = iMarkerArea.Height() - markerSize.iHeight; + TInt pos = ( pixelRange * ( iValue - MinimumValue() ) / Range() ); + + p.iX = iMarkerArea.iTl.iX; + if ( AknLayoutUtils::PenEnabled() && + iMarkerArea.Contains( iExt->iPenInputPos ) && + &Window() != NULL ) + { + if( !iExt->IsFlagSet( CAknSliderExtension::EFlagValueStepChange ) || + ( iExt->IsFlagSet( CAknSliderExtension::EFlagDraggingThumb ) && + iExt->IsFlagSet( CAknSliderExtension::EFlagPointerDown ) ) ) + { + p.iY = iExt->iPenInputPos.iY - ( markerSize.iHeight ) / 2; + } + else + { + p.iY = iMarkerArea.iBr.iY - pos - markerSize.iHeight; + } + } + else + { + p.iY = iMarkerArea.iBr.iY - pos - markerSize.iHeight; + } + } + return p; + } + + +// ---------------------------------------------------------------------------- +// CondBlit +// +// Helper C-function for conditional blitting, static to make the function +// visible to this compilation unit only. +// ---------------------------------------------------------------------------- +// +inline static void CondBlit( CWindowGc& aGc, const TPoint& aPoint, + const CFbsBitmap* aBitmap, const TSize& aSourceSize, + const CFbsBitmap* aMask, TBool aInvertMask = ETrue ) + { + const TPoint origin( 0, 0 ); + + aGc.SetBrushStyle( CGraphicsContext::ENullBrush ); + aGc.SetPenStyle( CGraphicsContext::ENullPen ); + aGc.SetBrushColor( AKN_LAF_COLOR( 0 ) ); + aGc.SetPenColor( AKN_LAF_COLOR( 0 ) ); + + if ( aBitmap && aMask ) + { + aGc.BitBltMasked( aPoint, aBitmap, + TRect( origin, aSourceSize ), + aMask, aInvertMask ); + } + else if ( aBitmap ) + { + aGc.BitBlt( aPoint, aBitmap, TRect( origin, aSourceSize) ); + } + else + { + // If no bitmap resource, it doesn't need to render default color any more + /*aGc.SetBrushStyle( CGraphicsContext::ESolidBrush ); + aGc.SetBrushColor( AKN_LAF_COLOR( KAknSliderDefaultDrawColor ) ); + aGc.SetPenStyle( CGraphicsContext::ESolidPen ); + aGc.SetPenColor( AKN_LAF_COLOR( KAknSliderDefaultDrawColor ) ); + aGc.DrawRect( TRect( aPoint, aSourceSize ) );*/ + } + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::DrawHorizontal +// ---------------------------------------------------------------------------- +// +void CAknSlider::DrawHorizontal( TBool aDrawMarker ) const + { + CWindowGc& gc = SystemGc(); + gc.SetBrushStyle( CGraphicsContext::ENullBrush ); + gc.SetBrushColor( AKN_LAF_COLOR( 0 ) ); + gc.SetPenColor( AKN_LAF_COLOR( 0 ) ); + + MAknsSkinInstance* skin = AknsUtils::SkinInstance(); + MAknsControlContext* cc = NULL; + + if ( AknsUtils::AvkonSkinEnabled() ) + { + cc = AknsDrawUtils::ControlContext( this ); + } + + if ( !FindBackground() ) + { + AknsDrawUtils::Background( skin, cc, this, gc, Rect() ); + } + + // Don't draw slider in form view mode + if ( !( Layout() == EAknSettingsItemSliderLayout || + Layout() == EAknSettingsItemSliderLayoutWithGraphics || + Layout() == EAknSliderLayoutVertical || + Layout() == EAknSliderLayoutHorizontal || + iEditable ) ) + { + return; + } + + DrawHorizontalLine( gc ); // Draw line and end caps + + // Draw the tick marks, if any + if ( iExt->IsFlagSet( CAknSliderExtension::EFlagTickMarksEnabled ) ) + { + DrawHorizontalTickMarks( gc ); + } + + // Draw the marker + if ( iExt->IsFlagSet( CAknSliderExtension::EFlagMarkerEnabled ) && + aDrawMarker ) + { + TRect rect; + TAknSliderGfx gfx; + + GetMarkerRect( rect ); + if ( iExt->IsFlagSet( CAknSliderExtension::EFlagPointerDown ) ) + { + FetchGfx( gfx, EElemMarkerSelected, rect.Size() ); + } + else + { + FetchGfx( gfx, EElemMarker, rect.Size() ); + } + + CondBlit( gc, rect.iTl, gfx.iRgb, rect.Size(), gfx.iMask, ETrue ); + } + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::DrawVertical +// ---------------------------------------------------------------------------- +// +void CAknSlider::DrawVertical( TBool aDrawMarker ) const + { + CWindowGc& gc = SystemGc(); + gc.SetBrushStyle( CGraphicsContext::ENullBrush ); + gc.SetBrushColor( AKN_LAF_COLOR( 0 ) ); + gc.SetPenColor( AKN_LAF_COLOR( 0 ) ); + + // Don't draw slider in form view mode + if ( !( Layout() == EAknSettingsItemSliderLayout || + Layout() == EAknSettingsItemSliderLayoutWithGraphics || + Layout() == EAknSliderLayoutVertical|| + Layout() == EAknSliderLayoutHorizontal || + iEditable ) ) + { + return; + } + + DrawVerticalLine( gc ); // Draw line and end caps + + // Draw the tick marks, if any + if ( iExt->IsFlagSet( CAknSliderExtension::EFlagTickMarksEnabled ) ) + { + DrawVerticalTickMarks( gc ); + } + + // Draw the marker + if ( iExt->IsFlagSet( CAknSliderExtension::EFlagMarkerEnabled ) && + aDrawMarker ) + { + TRect rect; + TAknSliderGfx gfx; + + GetMarkerRect( rect ); + if ( iExt->IsFlagSet( CAknSliderExtension::EFlagPointerDown ) ) + { + FetchGfx( gfx, EElemMarkerSelected, rect.Size() ); + } + else + { + FetchGfx( gfx, EElemMarker, rect.Size() ); + } + + CondBlit( gc, rect.iTl, gfx.iRgb, rect.Size(), gfx.iMask, ETrue ); + } + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::DrawHorizontalLine +// ---------------------------------------------------------------------------- +// +void CAknSlider::DrawHorizontalLine( CWindowGc& aGc ) const + { + TPoint pos; + TSize size; + TAknSliderGfx gfx; + + TRect mrect; + GetMarkerRect( mrect ); + TInt markerW2 = mrect.Width() / 2; + + // End caps and line use the same height + size = iExt->iLeftCapRect.Size(); + + // Draw the left cap, if any + if ( iExt->iLeftCapRect.Size().iWidth > 0 ) + { + pos = iExt->iLeftCapRect.iTl; + FetchGfx( gfx, EElemEmptyLeftCap, size ); + CondBlit( aGc, pos, gfx.iRgb, size, gfx.iMask ); + + // Fill the left cap if needed + if ( iExt->IsFlagSet( CAknSliderExtension::EFlagFillEnabled ) && + iValue != MinimumValue()) + { + FetchGfx( gfx, EElemFilledLeftCap, size ); + CondBlit( aGc, pos, gfx.iRgb, size, gfx.iMask ); + } + } + + // Draw the right cap, if any + if ( iExt->iRightCapRect.Size().iWidth > 0 ) + { + pos = iExt->iRightCapRect.iTl; + FetchGfx( gfx, EElemEmptyRightCap, size ); + CondBlit( aGc, pos, gfx.iRgb, size, gfx.iMask ); + + // Fill the right cap if needed + if ( iExt->IsFlagSet( CAknSliderExtension::EFlagFillEnabled ) && + iValue >= MaximumValue() ) + { + FetchGfx( gfx, EElemFilledRightCap, size ); + CondBlit( aGc, pos, gfx.iRgb, size, gfx.iMask ); + } + } + + // Draw the line + FetchGfx( gfx, EElemEmptyLine, iLineRect.Size() ); + CondBlit( aGc, iLineRect.iTl, gfx.iRgb, iLineRect.Size(), gfx.iMask ); + + // Draw the line filling, if any + if ( iExt->IsFlagSet( CAknSliderExtension::EFlagFillEnabled ) ) + { + if( Layout() == EAknSliderLayoutHorizontal ) + { + //pos.SetXY( iLineRect.iTl.iX + mrect.Width(), mrect.iTl.iY ); + pos.SetXY( iLineRect.iTl.iX, mrect.iTl.iY ); + size = iLineRect.Size(); + FetchGfx( gfx, EElemFilledLine, size ); + //size.iWidth = iLineRect.iBr.iX - ( mrect.iTl.iX + mrect.Width() ); + size.iWidth = mrect.iTl.iX - iLineRect.iTl.iX; + + + if ( MaximumValue() == iValue ) + { + pos = iLineRect.iTl; + size.iWidth = iLineRect.Width(); + } + if ( MinimumValue() == iValue ) + { + //pos.SetXY( iLineRect.iTl.iX, mrect.iTl.iY + markerH2/*iLineRect.iBr.iY*/ ); + //size.iHeight = size.iHeight - markerH2; + } + + CondBlit( aGc, iLineRect.iTl, gfx.iRgb, size, gfx.iMask ); + } + else + { + size.iWidth = mrect.iTl.iX + markerW2 - iLineRect.iTl.iX ; + FetchGfx( gfx, EElemFilledLine, size ); + if ( MaximumValue() == iValue ) + { + size.iWidth = iLineRect.Width(); + } + + CondBlit( aGc, iLineRect.iTl, gfx.iRgb, size, gfx.iMask ); + } + } + } + +// ---------------------------------------------------------------------------- +// RectBlit +// +// Helper C-function for conditional blitting, static to make the function +// visible to this compilation unit only. +// ---------------------------------------------------------------------------- +// +inline static void RectBlit( CWindowGc& aGc, const TPoint& aTl, + const TSize& aSize, const TInt aPosY, + const CFbsBitmap* aBitmap, const CFbsBitmap* aMask ) + { + aGc.SetBrushStyle( CGraphicsContext::ENullBrush ); + aGc.SetPenStyle( CGraphicsContext::ENullPen ); + aGc.SetBrushColor( AKN_LAF_COLOR( 0 ) ); + aGc.SetPenColor( AKN_LAF_COLOR( 0 ) ); + + if ( aBitmap && aMask ) + { + aGc.BitBltMasked( aTl, + aBitmap, + TRect( TPoint( 0, aPosY ), + TSize( aSize.iWidth, aSize.iHeight - aPosY ) ), + aMask, + ETrue ); + } + else if ( aBitmap ) + { + aGc.BitBlt( aTl, + aBitmap, + TRect( TPoint(0, aPosY), + TSize( aSize.iWidth, aSize.iHeight - aPosY ) ) ); + } + else + { + // If no bitmap resource, it doesn't need to render default color any more + /*aGc.SetBrushStyle( CGraphicsContext::ESolidBrush ); + aGc.SetBrushColor( AKN_LAF_COLOR( KAknSliderDefaultDrawColor ) ); + aGc.SetPenStyle( CGraphicsContext::ESolidPen ); + aGc.SetPenColor( AKN_LAF_COLOR( KAknSliderDefaultDrawColor ) ); + aGc.DrawRect( TRect( aTl, TSize( aSize.iWidth, aSize.iHeight - aPosY ) ) );*/ + } + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::DrawVerticalLine +// ---------------------------------------------------------------------------- +// +void CAknSlider::DrawVerticalLine( CWindowGc& aGc ) const + { + TPoint pos; + TSize size; + TAknSliderGfx gfx; + + TRect mrect; + GetMarkerRect( mrect ); + + TInt markerH2 = mrect.Height() / 2; + TInt fromTop(0); + + // End caps and line use the same width + size = iExt->iLeftCapRect.Size(); + + // Draw the bottom cap, if any + if ( iExt->iLeftCapRect.Size().iWidth > 0 ) + { + pos = iExt->iLeftCapRect.iTl; + FetchGfx( gfx, EElemEmptyLeftCap, size ); + CondBlit( aGc, pos, gfx.iRgb, size, gfx.iMask ); + + // Fill the bottom cap if needed + if ( iExt->IsFlagSet( CAknSliderExtension::EFlagFillEnabled ) ) + { + //bottom cap filled when all the line filled + FetchGfx( gfx, EElemFilledLeftCap, size ); + RectBlit( aGc, pos, size, fromTop, + gfx.iRgb, gfx.iMask ); + } + } + + // Draw the top cap, if any + if ( iExt->iRightCapRect.Size().iWidth > 0 ) + { + pos = pos = iExt->iRightCapRect.iTl; + + FetchGfx( gfx, EElemEmptyRightCap, size ); + CondBlit( aGc, pos, gfx.iRgb, size, gfx.iMask ); + + if ( iExt->IsFlagSet( CAknSliderExtension::EFlagFillEnabled ) && + iValue >= MaximumValue() ) + { + FetchGfx( gfx, EElemFilledRightCap, size ); + RectBlit( aGc, pos, size, fromTop, gfx.iRgb, gfx.iMask ); + } + } + + // Draw the line + FetchGfx( gfx, EElemEmptyLine, iLineRect.Size() ); + CondBlit( aGc, iLineRect.iTl, gfx.iRgb, iLineRect.Size(), gfx.iMask ); + + // Draw the line filling, if any + if ( iExt->IsFlagSet( CAknSliderExtension::EFlagFillEnabled ) ) + { + pos.SetXY( iLineRect.iTl.iX, mrect.iTl.iY + mrect.Height() ); + size = iLineRect.Size(); + FetchGfx( gfx, EElemFilledLine, size ); + size.iHeight = iLineRect.iBr.iY - ( mrect.iTl.iY + mrect.Height() ); + + + if ( MaximumValue() == iValue ) + { + pos = iLineRect.iTl; + size.iHeight = iLineRect.Height(); + } + if ( MinimumValue() == iValue ) + { + //pos.SetXY( iLineRect.iTl.iX, mrect.iTl.iY + markerH2/*iLineRect.iBr.iY*/ ); + //size.iHeight = size.iHeight - markerH2; + } + RectBlit( aGc, pos, iLineRect.Size(), + iLineRect.Height() - size.iHeight, + gfx.iRgb, gfx.iMask ); + } + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::FetchGfx +// ---------------------------------------------------------------------------- +// +void CAknSlider::FetchGfx( + TAknSliderGfx& aGfx, TInt aElement, const TSize& aSize ) const + { + if ( aElement < 0 || aElement > EElemMarkerSelected ) + { + Panic( EAknPanicInvalidValue ); + } + + TScaleMode mode = EAspectRatioNotPreserved; // default ratio + + // Step 1: Check if custom graphics have been defined for this element. + if ( !iExt->UsesDefaultGraphics( aElement ) || + Layout() == EAknSliderLayoutVertical || + Layout() == EAknSliderLayoutHorizontal ) + { + iExt->GetGfx( aGfx, aElement ); + if ( ( aElement == EElemEmptyLine ) || ( aElement == EElemFilledLine ) ) + { + mode = EAspectRatioNotPreserved; + } + + if ( aGfx.iRgb ) + { + AknIconUtils::SetSize( aGfx.iRgb, aSize, mode ); + } + if ( aGfx.iMask ) + { + AknIconUtils::SetSize( aGfx.iMask, aSize, mode ); + } + + return; + } + else + { + aGfx.iRgb = NULL; + aGfx.iMask = NULL; + } + + // Step 2: No custom graphics, try Avkon icons. + if( Layout() != EAknSliderLayoutVertical && Layout() != EAknSliderLayoutHorizontal )//vertical is always customized + { + if ( EElemEmptyLine == aElement ) + { + aGfx.iRgb = iExt->iLineIcon; + aGfx.iMask = iExt->iLineIconMask; + } + else if ( EElemMarker == aElement || + EElemMarkerSelected == aElement ) + { + aGfx.iRgb = iMarkerBmp; + aGfx.iMask = iMarkerMaskBmp; + } + } + + //resize the graphic + if ( aGfx.iRgb ) + { + AknIconUtils::SetSize( aGfx.iRgb, aSize, mode ); + } + if ( aGfx.iMask ) + { + AknIconUtils::SetSize( aGfx.iMask, aSize, mode ); + } + + } + +// ---------------------------------------------------------------------------- +// CAknSlider::EnableDrag +// ---------------------------------------------------------------------------- +// +EXPORT_C void CAknSlider::EnableDrag() + { + EnableDragEvents(); + } + +// ---------------------------------------------------------------------------- +// CAknSlider::SetLabelColor +// ---------------------------------------------------------------------------- +// + +void CAknSlider::SetLabelColor() + { + MAknsSkinInstance* skin = AknsUtils::SkinInstance(); + TRgb color; + TInt error; + if ( Layout() != EAknSettingsItemSliderLayout && + Layout() != EAknSettingsItemSliderLayoutWithGraphics && + Layout() != EAknSliderLayoutVertical && + Layout() != EAknSliderLayoutHorizontal ) + { + error = AknsUtils::GetCachedColor( skin, color, + KAknsIIDQsnTextColors, EAknsCIQsnTextColorsCG8 ); + } + else + { + error = AknsUtils::GetCachedColor( skin, color, + KAknsIIDQsnTextColors, EAknsCIQsnTextColorsCG7 ); + } + + if ( !error ) + { + // ignore error + TRAP_IGNORE( AknLayoutUtils::OverrideControlColorL( + *iMinLabel, EColorLabelText, color ) ); + TRAP_IGNORE( AknLayoutUtils::OverrideControlColorL( + *iMaxLabel, EColorLabelText, color ) ); + TRAP_IGNORE( AknLayoutUtils::OverrideControlColorL( + *iValueLabel, EColorLabelText, color ) ); + } + + AknsUtils::GetCachedColor( skin, color, KAknsIIDQsnLineColors, + EAknsCIQsnLineColorsCG8 ); + iColor = color; + } + +// ---------------------------------------------------------------------------- +// CAknSlider::ReportMarkerDragEvent +// ---------------------------------------------------------------------------- +// +void CAknSlider::ReportMarkerDragEvent( TBool aEnable ) + { + iExt->iReportMarkerDragEvent = aEnable; + } + +void CAknSlider::SuppressDrawing( TBool aSuppress ) + { + iExt->iNoDraw = aSuppress; + } + +// ---------------------------------------------------------------------------- +// CAknSlider::FocusChanged +// ---------------------------------------------------------------------------- +// +EXPORT_C void CAknSlider::FocusChanged(TDrawNow /*aDrawNow*/) + { + if ( !IsFocused() ) + { + iExt->ClearFlag( CAknSliderExtension::EFlagPointerDown ); + iExt->ClearFlag( CAknSliderExtension::EFlagDraggingThumb ); + // Marker icon changes - draw + if ( !iExt->iNoDraw ) + { + DrawDeferred(); + } + } + } + +// ---------------------------------------------------------------------------- +// CAknSlider::StartFeedback +// ---------------------------------------------------------------------------- +// +void CAknSlider::StartFeedback( const TPointerEvent* aPointerEvent, TTimeIntervalMicroSeconds32 aTimeout ) + { + MTouchFeedback* feedback = MTouchFeedback::Instance(); + if ( feedback ) + { + TInt intensity = KStableFeedbackIntesity; + if ( SliderData()->iFeedbackStyle == EAknSliderFbDynamic ) + { + intensity = FeedbackIntensity(); + } + feedback->StartFeedback( this, ETouchContinuousSlider, aPointerEvent, intensity, aTimeout ); + iExt->SetFlag( CAknSliderExtension::EFlagPlayingContinuousFb ); + } + } + +// ---------------------------------------------------------------------------- +// CAknSlider::StopFeedback +// ---------------------------------------------------------------------------- +// +void CAknSlider::StopFeedback() + { + iExt->ClearFlag( CAknSliderExtension::EFlagPlayingContinuousFb ); + MTouchFeedback* feedback = MTouchFeedback::Instance(); + if ( feedback ) + { + feedback->StopFeedback( this ); + } + } + +// ---------------------------------------------------------------------------- +// CAknSlider::ModifyFeedback +// ---------------------------------------------------------------------------- +// +void CAknSlider::ModifyFeedback() + { + TInt intensity = FeedbackIntensity(); + MTouchFeedback* feedback = MTouchFeedback::Instance(); + if ( feedback ) + { + feedback->ModifyFeedback( this, intensity ); + } + } + + +// ---------------------------------------------------------------------------- +// CAknSlider::FeedbackIntensity +// ---------------------------------------------------------------------------- +// +TInt CAknSlider::FeedbackIntensity() + { + TRect mrect; + GetMarkerRect( mrect ); + TBool hor = iExt->IsFlagSet( CAknSliderExtension::EFlagHorizontal ); + + if ( hor ) + { + TInt position = mrect.iTl.iX - iMarkerArea.iTl.iX; + return TReal( position )/TReal( iMarkerArea.Width()-mrect.Width() )*100; + } + else + { + TInt position = iMarkerArea.iBr.iY - mrect.iBr.iY; + return TReal( position )/TReal( iMarkerArea.Height()-mrect.Height() )*100; + } + } + + +// --------------------------------------------------------------------------- +// Provides the touch active area for setting page slider. +// --------------------------------------------------------------------------- +// +TRect CAknSlider::TouchActiveArea() const + { + 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(); + + // Convert main pane rect location to slider window coordinates + touchActiveArea.Move( + touchActiveArea.iTl.iX - winPosition.iX, + touchActiveArea.iTl.iY - winPosition.iY ); + return touchActiveArea; + } + +// End of File +