idlehomescreen/xmluirendering/renderingplugins/xnvolumecontrolfactory/src/xnvolumecontroladapter.cpp
/*
* Copyright (c) 2005-2007 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description: Implementation for wrapper for a volume control component
*
*/
#include <e32base.h>
#include <coecntrl.h>
#include <barsread.h>
#include <barsc.h>
#include <Aknvolumecontrol.h>
#include "xnnodepluginif.h"
#include "xndompropertyvalue.h"
#include "xndomproperty.h"
#include "xndomlist.h"
#include "xnproperty.h"
#include "xncomponent.h"
#include "xnuienginepluginif.h"
#include "xncomponentnodeimpl.h"
#include "xncontroladapter.h"
#include "xntype.h"
#include "xnvolumecontroladapter.h"
#include "xnvolumecontrolobserver.h"
#include "xnvolumecontrol.rsg"
_LIT( KResourceFileName, "z:\\resource\\plugins\\xn3volumecontrol.rsc" );
// ============================ MEMBER FUNCTIONS ===============================
// -----------------------------------------------------------------------------
// CXnVolumeControlAdapter::NewL
// Symbian static 1st phase constructor
// -----------------------------------------------------------------------------
//
CXnVolumeControlAdapter* CXnVolumeControlAdapter::NewL(CXnControlAdapter* aParent,
CXnNodePluginIf& aNode)
{
CXnVolumeControlAdapter* self = new( ELeave ) CXnVolumeControlAdapter(aParent, aNode);
CleanupStack::PushL( self );
self->ConstructL();
CleanupStack::Pop();
return self;
}
// -----------------------------------------------------------------------------
// CXnVolumeControlAdapter::CXnVolumeControlAdapter
// C++ default constructor
// -----------------------------------------------------------------------------
//
CXnVolumeControlAdapter::CXnVolumeControlAdapter(CXnControlAdapter* aParent,
CXnNodePluginIf& aNode)
: iParent( aParent ), iNode( aNode )
{
}
// -----------------------------------------------------------------------------
// CXnVolumeControlAdapter::~CXnVolumeControlAdapter
// C++ destructor
// -----------------------------------------------------------------------------
//
CXnVolumeControlAdapter::~CXnVolumeControlAdapter()
{
delete iVolumeControl;
}
// -----------------------------------------------------------------------------
// CXnVolumeControlAdapter::ConstructL
// Symbian 2nd phase constructor can leave.
// -----------------------------------------------------------------------------
//
void CXnVolumeControlAdapter::ConstructL()
{
ConstructVolumeControlL();
iVolumeControl->SetValue( ValueL() );
CXnControlAdapter::ConstructL( iNode );
}
// -----------------------------------------------------------------------------
// CXnVolumeControlAdapter::ConstructVolumeControL
// -----------------------------------------------------------------------------
//
void CXnVolumeControlAdapter::ConstructVolumeControlL()
{
delete iVolumeControl;
iVolumeControl = NULL;
iVolumeControl = new ( ELeave ) CAknVolumeControl;
iVolumeControl->SetContainerWindowL( *iParent );
iVolumeControl->SetBackground( this );
RFs fsSession;
TInt err( fsSession.Connect() );
if( err )
{
User::Leave( err );
}
CleanupClosePushL( fsSession );
RResourceFile resourceFile;
resourceFile.OpenL( fsSession, KResourceFileName );
CleanupClosePushL( resourceFile );
HBufC8* resource = resourceFile.AllocReadLC( R_XNVOLUMECONTROLDYNAMIC );
TResourceReader reader;
reader.SetBuffer( resource );
iVolumeControl->ConstructFromResourceL( reader );
iVolumeControl->SetRect( iNode.Rect() );
CleanupStack::PopAndDestroy( 3, &fsSession ); // resource, resourceFile, fsSession
SetVolumeControlPropertiesL();
}
// -----------------------------------------------------------------------------
// CXnVolumeControlAdapter::SetObserver
// -----------------------------------------------------------------------------
//
void CXnVolumeControlAdapter::SetObserver( MXnVolumeControlObserver* aObserver )
{
iObserver = aObserver;
}
// -----------------------------------------------------------------------------
// CXnVolumeControlAdapter::SetValue
// -----------------------------------------------------------------------------
//
void CXnVolumeControlAdapter::SetValueL( TInt aValue )
{
TInt minRange;
TInt maxRange;
GetRangeL( minRange, maxRange );
if( aValue >= minRange && aValue <= maxRange )
{
CXnDomStringPool& sp = iNode.UiEngineL()->StringPool();
CXnDomPropertyValue* value = CXnDomPropertyValue::NewL( &sp );
CleanupStack::PushL( value );
value->SetFloatValueL( CXnDomPropertyValue::ENumber, aValue );
CXnProperty* valueProperty = CXnProperty::NewL( XnPropertyNames::action::KValue, value, sp );
CleanupStack::Pop( value );
CleanupStack::PushL( valueProperty );
iNode.SetPropertyL( valueProperty );
CleanupStack::Pop( valueProperty );
}
}
// -----------------------------------------------------------------------------
// CXnVolumeControlAdapter::Value
// -----------------------------------------------------------------------------
//
TInt CXnVolumeControlAdapter::ValueL()
{
return GetCurrentValueL();
}
// -----------------------------------------------------------------------------
// CXnVolumeControlAdapter::SetRange
// -----------------------------------------------------------------------------
//
void CXnVolumeControlAdapter::SetRangeL( TInt aMinimumValue, TInt aMaximumValue )
{
CXnDomStringPool& sp = iNode.UiEngineL()->StringPool();
// Set min value property
CXnDomPropertyValue* minValue = CXnDomPropertyValue::NewL( &sp );
CleanupStack::PushL( minValue );
minValue->SetFloatValueL( CXnDomPropertyValue::ENumber, aMinimumValue );
CXnProperty* minValueProperty = CXnProperty::NewL( XnPropertyNames::volumecontrol::KMinRange, minValue, sp );
CleanupStack::Pop( minValue );
CleanupStack::PushL( minValueProperty );
iNode.SetPropertyL( minValueProperty );
CleanupStack::Pop( minValueProperty );
// Set max value property
CXnDomPropertyValue* maxValue = CXnDomPropertyValue::NewL( &sp );
CleanupStack::PushL( maxValue );
maxValue->SetFloatValueL( CXnDomPropertyValue::ENumber, aMaximumValue );
CXnProperty* maxValueProperty = CXnProperty::NewL( XnPropertyNames::volumecontrol::KMaxRange, maxValue, sp );
CleanupStack::Pop( maxValue );
CleanupStack::PushL( maxValueProperty );
iNode.SetPropertyL( maxValueProperty );
CleanupStack::Pop( maxValueProperty );
iVolumeControl->SetRange( aMinimumValue, aMaximumValue );
iSteps = aMaximumValue - aMinimumValue;
}
// -----------------------------------------------------------------------------
// CXnVolumeControlAdapter::GetRange
// -----------------------------------------------------------------------------
//
void CXnVolumeControlAdapter::GetRangeL( TInt& aMinimumValue, TInt& aMaximumValue )
{
CXnProperty* minRange = iNode.GetPropertyL( XnPropertyNames::volumecontrol::KMinRange );
if ( minRange )
{
aMinimumValue = static_cast<TInt>( minRange->FloatValueL() );
}
else
{
aMinimumValue = 1;
}
CXnProperty* maxRange = iNode.GetPropertyL( XnPropertyNames::volumecontrol::KMaxRange );
if ( maxRange )
{
aMaximumValue = static_cast<TInt>( maxRange->FloatValueL() );
}
else
{
aMaximumValue = aMinimumValue;
}
}
// -----------------------------------------------------------------------------
// CXnVolumeControlAdapter::DoHandlePropertyChangeL
// -----------------------------------------------------------------------------
//
void CXnVolumeControlAdapter::DoHandlePropertyChangeL( CXnProperty* aProperty )
{
if (aProperty)
{
TInt minValue;
TInt maxValue;
GetRangeL( minValue, maxValue );
if( aProperty->Property()->Name() == XnPropertyNames::volumecontrol::KVolumeLevelAdjustment )
{
CXnDomStringPool& sp = iNode.UiEngineL()->StringPool();
CXnDomPropertyValue* value = CXnDomPropertyValue::NewL( &sp );
CleanupStack::PushL( value );
const TDesC8& strValue = aProperty->StringValue();
// Increase volume
if( strValue == XnPropertyNames::volumecontrol::KIncrease )
{
TInt newValue = ValueL() + 1;
if( newValue >= minValue && newValue <= maxValue )
{
value->SetFloatValueL( CXnDomPropertyValue::ENumber, ValueL() + 1 );
}
else
{
CleanupStack::PopAndDestroy( value );
return;
}
}
// Decrease volume
else if( strValue == XnPropertyNames::volumecontrol::KDecrease )
{
TInt newValue = ValueL() - 1;
if( newValue >= minValue && newValue <= maxValue )
{
value->SetFloatValueL( CXnDomPropertyValue::ENumber, ValueL() - 1 );
}
else
{
CleanupStack::PopAndDestroy( value );
return;
}
}
// Mute
else if( strValue == XnPropertyNames::volumecontrol::KMute )
{
if( iMuted )
{
value->SetFloatValueL( CXnDomPropertyValue::ENumber, iMutedValue );
iMuted = EFalse;
}
else
{
value->SetFloatValueL( CXnDomPropertyValue::ENumber, minValue );
iMutedValue = GetCurrentValueL();
iMuted = ETrue;
}
}
CXnProperty* valueProperty = CXnProperty::NewL( XnPropertyNames::action::KValue, value, sp );
CleanupStack::Pop( value );
CleanupStack::PushL( valueProperty );
iNode.SetPropertyL( valueProperty );
CleanupStack::Pop( valueProperty );
}
else if( aProperty->Property()->Name() == XnPropertyNames::action::KValue )
{
TInt newValue = static_cast<TInt>( aProperty->FloatValueL() );
if( newValue >= minValue && newValue <= maxValue )
{
iVolumeControl->SetValue( newValue );
NotifyObserverL();
}
}
}
else
{
return;
}
}
// -----------------------------------------------------------------------------
// CXnVolumeControlAdapter::HandleScreenDeviceChangedL
// -----------------------------------------------------------------------------
//
void CXnVolumeControlAdapter::HandleScreenDeviceChangedL()
{
ConstructVolumeControlL();
CXnControlAdapter::HandleScreenDeviceChangedL();
}
// ---------------------------------------------------------
// CXnVolumeControlAdapter::SizeChanged()
// Called by framework when the view size is changed
// (other items were commented in a header).
// ---------------------------------------------------------
//
void CXnVolumeControlAdapter::SizeChanged()
{
CXnControlAdapter::SizeChanged();
if( iVolumeControl )
{
iVolumeControl->SetRect( iNode.Rect() );
}
}
// -----------------------------------------------------------------------------
// CXnVolumeControlAdapter::CountComponentControls
// Returns the number of component controls.
// -----------------------------------------------------------------------------
//
TInt CXnVolumeControlAdapter::CountComponentControls() const
{
return 1;
}
// -----------------------------------------------------------------------------
// CXnVolumeControlAdapter::ComponentControl
// Returns the component control of the given index
// -----------------------------------------------------------------------------
//
CCoeControl* CXnVolumeControlAdapter::ComponentControl( TInt aIndex ) const
{
if( aIndex == 0 )
{
return iVolumeControl;
}
return NULL;
}
// -----------------------------------------------------------------------------
// CXnNewstickerAdapter::Draw
// -----------------------------------------------------------------------------
//
void CXnVolumeControlAdapter::Draw(CWindowGc& aGc, const CCoeControl& /*aControl*/,
const TRect& aRect) const
{
CXnControlAdapter::Draw( aRect, aGc );
}
// -----------------------------------------------------------------------------
// CXnVolumeControlAdapter::Draw
// Draws the text component
// -----------------------------------------------------------------------------
//
void CXnVolumeControlAdapter::Draw(const TRect& aRect) const
{
CXnControlAdapter::Draw( aRect );
}
// ----------------------------------------------------------------------------
// CXnVolumeControlAdapter::HandlePointerEventL
// Handles the pointer events.
// ----------------------------------------------------------------------------
//
void CXnVolumeControlAdapter::HandlePointerEventL( const TPointerEvent& aPointerEvent )
{
TRect rect( iVolumeControl->Rect() );
TReal incrementWidth( TReal( rect.Width() ) / iSteps );
TInt leftX( rect.iTl.iX );
if( aPointerEvent.iType == TPointerEvent::EButton1Down ||
aPointerEvent.iType == TPointerEvent::EMove && iButton1Down )
{
// By default change the value
TBool valueSet( EFalse );
for( TInt i = 1; i <= iSteps && !valueSet; i++ )
{
// Calculate pixel range
TReal minX( leftX + ( ( i - 1 ) * incrementWidth ) );
TReal maxX( minX + incrementWidth );
if( aPointerEvent.iPosition.iX >= minX && aPointerEvent.iPosition.iX <= maxX )
{
TBool changeValue( ETrue );
if( iHitRect == TRect::EUninitialized )
{
// Initialize
iHitRect = TRect( minX, rect.iTl.iY, maxX, rect.iBr.iY );
}
else if( !( iHitRect.Contains( aPointerEvent.iPosition ) ) )
{
// Reset, as position is changed
iHitRect = TRect( TRect::EUninitialized );
changeValue = EFalse;
}
else
{
// Still in same slot, do not change value
changeValue = EFalse;
}
if( changeValue )
{
TInt value = ValueL();
if( value == i )
{
value = value - 1;
}
else
{
value = i;
}
//SetValueL will notify also the observer
SetValueL( value );
DrawDeferred();
valueSet = ETrue;
}
}
}
}
if( aPointerEvent.iType == TPointerEvent::EButton1Down )
{
iButton1Down = ETrue;
}
else if( aPointerEvent.iType == TPointerEvent::EButton1Up )
{
// Reset
iButton1Down = EFalse;
iHitRect = TRect( TRect::EUninitialized );
}
}
// ----------------------------------------------------------------------------
// CXnVolumeControlAdapter::SetVolumeControlProperties
// Sets CSS properties for the volume control
// ----------------------------------------------------------------------------
//
void CXnVolumeControlAdapter::SetVolumeControlPropertiesL()
{
// Read minrange property
CXnProperty* minRange = iNode.GetPropertyL( XnPropertyNames::volumecontrol::KMinRange );
TInt minValue = 0;
if( minRange )
{
minValue = static_cast<TInt>( minRange->FloatValueL() );
}
// Read maxrange property
CXnProperty* maxRange = iNode.GetPropertyL( XnPropertyNames::volumecontrol::KMaxRange );
TInt maxValue = 20;
if( maxRange )
{
maxValue = static_cast<TInt>( maxRange->FloatValueL() );
}
SetRangeL( minValue, maxValue );
TInt midRange( iSteps / 2 );
TInt volValue( 0 );
if( iVolumeControl->Value() < minValue ||
iVolumeControl->Value() > maxValue )
{
// Set around to mid
volValue = midRange;
}
// Read value property
CXnProperty* value = iNode.GetPropertyL( XnPropertyNames::action::KValue );
if( value )
{
TInt valueProp = static_cast< TInt >( value->FloatValueL() );
if( valueProp >= minValue && valueProp <= maxValue )
{
volValue = valueProp;
}
}
SetValueL( volValue );
}
// ----------------------------------------------------------------------------
// CXnVolumeControlAdapter::GetCurrentValue
// ----------------------------------------------------------------------------
//
TInt CXnVolumeControlAdapter::GetCurrentValueL()
{
CXnProperty* valueProperty = iNode.GetPropertyL( XnPropertyNames::action::KValue );
TInt retVal( 1 );
if ( valueProperty )
{
retVal = static_cast<TInt>( valueProperty->FloatValueL() );
}
return retVal;
}
// ----------------------------------------------------------------------------
// CXnVolumeControlAdapter::NotifyObserver
// ----------------------------------------------------------------------------
//
void CXnVolumeControlAdapter::NotifyObserverL()
{
if( iObserver )
{
iObserver->VolumeChanged( GetCurrentValueL() );
}
}