/*
* Copyright (c) 1997-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:
*
*/
#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
#include <uikon/eikdefmacros.h>
#endif
#include <eikscrlb.h>
#include <eikpanic.h>
#include <eikcoctlpanic.h>
#include <eikenv.h>
#include <AknLayout.lag>
#include <eikcba.h>
#include <AknsDrawUtils.h>
#include <AknUtils.h>
#include <aknappui.h>
#include <AknsUtils.h>
#include <AknLayout2ScalableDef.h>
#include <aknlayoutscalable_avkon.cdl.h>
#include <AknInfoPopupNoteController.h>
#include <aknpointereventmodifier.h>
#include <AknTasHook.h>
#include <touchfeedback.h>
#include "AknDoubleSpanScrollIndicator.h"
#include "eikscrlb.h"
#include "EIKSBEXT.H"
const TInt KScrollBarWidth=9;
// const TInt KScrollButtonHeight=10;
// const TInt KArrowHeadScrollBarLength=20;
// Constants for double span scrollbar
const TInt KAknDoubleSpanScrollBarWidth = 6;
const TInt KDoubleSpanMaxModelValue = 0x1FFF7FFF;
const TInt KDoubleSpanMinModelValue = -0x1FFF7FFF;
const TInt16 KDoubleSpanMaxScaleValue = 0x3FFF;
const TInt16 KDoubleSpanMinScaleValue = 1;
const TInt KDoubleSpanMaxRawValue = 0x8000;
// Mask values for double span scrollbar
const TUint KDoubleSpanModelMaskBitsHigh = 0xFFFF0000;
const TUint KDoubleSpanModelMaskBitsLow = 0x0000FFFF;
const TUint KDoubleSpanModelMaskBitsScale = 0x3FFF0000;
const TUint KDoubleSpanModelMaskBitsType = 0x3FFFFFFF;
const TUint16 KDoubleSpanModelMaskBitsScale16 = 0x3FFF;
const TInt KScrollRepeatTimeout = 250000; // 0.25 seconds
const TInt KScrollDragTimeout = 66000; // 0.66 seconds means 16 fps
EXPORT_C TBool TEikScrollBarModel::operator==(const TEikScrollBarModel aModel) const
{
return ((iScrollSpan==aModel.iScrollSpan)&(iThumbSpan==aModel.iThumbSpan)&(iThumbPosition==aModel.iThumbPosition));
}
EXPORT_C TEikScrollBarModel::TEikScrollBarModel(TInt aScrollSpan,TInt aThumbSpan,TInt aThumbPosition)
: iScrollSpan(aScrollSpan),
iThumbSpan(aThumbSpan),
iThumbPosition(aThumbPosition)
{}
EXPORT_C TBool TEikScrollBarModel::ScrollBarUseful() const
{
return iThumbSpan<iScrollSpan;
}
EXPORT_C TInt TEikScrollBarModel::MaxThumbPos() const
{
return iScrollSpan-iThumbSpan;
}
EXPORT_C void TEikScrollBarModel::CheckBounds()
// Ensure the thumbposition remains within it's valid range
{
iThumbPosition=Max(0,Min(iThumbPosition,iScrollSpan-1));
}
TEikScrollBarModel::TEikScrollBarModelType TEikScrollBarModel::ScrollBarModelType() const
{
TUint type = (~KDoubleSpanModelMaskBitsType) & iScrollSpan;
if (type == EAknDoubleSpanScrollBarModel)
{
return EAknDoubleSpanScrollBarModel;
}
else
{
return EEikScrollBarModel;
}
}
//
// CEikScrollBar class
//
EXPORT_C CEikScrollBar::~CEikScrollBar()
// Destructor
{
AKNTASHOOK_REMOVE();
DisconnectExternalFrames();
delete(iButtons.iIncreaseNudge);
delete(iButtons.iDecreaseNudge);
delete iExtension;
}
EXPORT_C CEikScrollBar::CEikScrollBar()
// Default constructor
{
SetNonFocusing();
SetComponentsToInheritVisibility();
AKNTASHOOK_ADD( this, "CEikScrollBar" );
}
EXPORT_C void CEikScrollBar::ConstructL(MEikScrollBarObserver* aScrollBarObserver,const CCoeControl* aParent,
TOrientation aOrientation,TInt /*aLength*/,TInt /*aScrollBarFlags*/)
// Second-phase construction
{
// If extension has not been created by deriving class, create default extension.
if (!iExtension)
{
iExtension = new(ELeave) CEikScrollBarExtension(this);
}
if(AknLayoutUtils::PenEnabled())
{
CEikScrollBarExtension* extension = static_cast<CEikScrollBarExtension*> (iExtension);
extension->SetScrollBarObserver(aScrollBarObserver);
}
CreateWindowL(aParent);
if(aParent)
SetObserver(aParent->Observer());
else
SetObserver(NULL);
iOrientation=aOrientation;
// Fix scrollbar frame's position to middle of cba
CreateRequiredComponentsL();
Window().SetPointerGrab(ETrue);
EnableDragEvents();
MakeVisible(EFalse);
ActivateL();
}
EXPORT_C TInt CEikScrollBar::CountComponentControls() const
{
TInt controlCount = 0;
if(iButtons.iIncreaseNudge)
{
controlCount++;
}
if(iButtons.iDecreaseNudge)
{
controlCount++;
}
return controlCount;
}
EXPORT_C CCoeControl* CEikScrollBar::ComponentControl(TInt aIndex) const
{
if (aIndex==0)
return iButtons.iIncreaseNudge;
else
return iButtons.iDecreaseNudge;
}
EXPORT_C void CEikScrollBar::SetLengthL(TInt /*aLength*/)
// Change the scrollbar's length. Will redraw
{
}
EXPORT_C void CEikScrollBar::SetModelL(const TEikScrollBarModel* aModel)
{
SetModel(aModel);
}
EXPORT_C void CEikScrollBar::SetModel(const TEikScrollBarModel* aModel)
// Change the scrollbar model
{
if (*aModel==iModel)
return;
DoSetModel(aModel);
}
EXPORT_C void CEikScrollBar::SetLengthAndModelL(TInt /*aLength*/,const TEikScrollBarModel* aModel)
// Change the length and model at once to avoid a double update of the scrollbar
{
SetModel(aModel);
}
EXPORT_C void CEikScrollBar::SetModelThumbPosition(TInt /*aThumbPos*/)
{
}
EXPORT_C void CEikScrollBar::SetFocusPosToThumbPos(TInt /*aFocusPosition*/)
{
}
EXPORT_C TInt CEikScrollBar::ThumbPosition() const
// Retrun the model's thumb position (eg in response to a scroll event)
{
if (iExtension)
{
return iExtension->ThumbPosition();
}
else
{
return 0;
}
}
EXPORT_C TInt CEikScrollBar::ScrollBarBreadth() const
// returns the height of a horizontal scrollbar or width of a vertical scrollbar
{
if (iExtension)
{
return iExtension->ScrollBarBreadth();
}
else
{
return 0;
}
}
EXPORT_C TInt CEikScrollBar::MinVisibleLength(const TInt /*aScrollBarFlags*/)
// STATIC - Calculates the minimum length in which scrollbar will remain "visible" (not necessarily with all it's components though)
{
return 0;
}
EXPORT_C void CEikScrollBar::SetDecreaseButtonsDimmed(TBool /*aDimmed*/)
// Dim out the decrease buttons
{
}
EXPORT_C void CEikScrollBar::SetIncreaseButtonsDimmed(TBool /*aDimmed*/)
// Dim out the increase buttons
{
}
EXPORT_C void CEikScrollBar::SetAllButtonsDimmed(TBool /*aDimmed*/)
// Dim out all buttons
{
}
void CEikScrollBar::CreateRequiredComponentsL()
// Allocates and constructs all the required components of the scrollbar
{
if (iExtension)
{
iExtension->CreateRequiredComponentsL();
}
}
EXPORT_C void CEikScrollBar::CreateButtonL(CAknScrollButton*& /*aButton*/,CAknScrollButton::TType /*aType*/)
// Create the appropriate button
{
}
void CEikScrollBar::DestroyButton(CAknScrollButton*& aButton)
// destroy a button
{
delete aButton;
aButton=NULL;
}
EXPORT_C void CEikScrollBar::SetButtonPositionL(CAknScrollButton* /*aButton*/)
// Calculates and sets a buttons position,making necessary adjustments for densely packed buttons
{
}
void CEikScrollBar::DoSetModel(const TEikScrollBarModel* aModel)
// Just change the internal model checking it's valid
{
if (iExtension)
{
iExtension->DoSetModel(aModel);
}
}
void CEikScrollBar::SizeChanged()
{
// Update position of components
if (iButtons.iIncreaseNudge)
{
TRAP_IGNORE(SetButtonPositionL(iButtons.iIncreaseNudge));
}
if (iButtons.iDecreaseNudge)
{
TRAP_IGNORE(SetButtonPositionL(iButtons.iDecreaseNudge));
}
}
EXPORT_C TInt CEikScrollBar::DefaultScrollBarBreadth()
{
return KScrollBarWidth;
}
EXPORT_C void CEikScrollBar::HandleControlEventL(CCoeControl* /*aControl*/, TCoeEvent /*aEventType*/)
{
}
EXPORT_C void CEikScrollBar::HandlePointerEventL(const TPointerEvent& aPointerEvent)
{
CEikBorderedControl::HandlePointerEventL(aPointerEvent);
}
EXPORT_C void CEikScrollBar::SetExtensionAreaType(TScrollBarExtensionAreaType aType)
{
if(ScrollBarType() == CEikScrollBar::EDoubleSpan)
{
CAknDoubleSpanScrollBarExtension* extension = static_cast<CAknDoubleSpanScrollBarExtension*> (iExtension);
extension->iExtensionType = aType;
}
}
EXPORT_C void* CEikScrollBar::ExtensionInterface( TUid /*aInterface*/ )
{
return NULL;
}
EXPORT_C void CEikScrollBar::Reserved_2()
{
}
EXPORT_C void CEikScrollBar::MakeVisible(TBool aVisible)
{
if (COMPARE_BOOLS(aVisible, IsVisible()))
return;
TAknWindowLineLayout lay(AKN_LAYOUT_WINDOW_Control_pane_elements_Line_1);
TAknLayoutRect lr;
lr.LayoutRect( Rect(), lay );
TRect r( lr.Rect() );
SetExtent( r.iTl, TSize( aVisible ? r.Width() : 0, 2 * r.Height() ) );
// Arrow head scroll bar will not be displayed
if ( iExtension->ScrollBarType() == CEikScrollBar::EArrowHead )
{
CCoeControl::MakeVisible( EFalse );
}
else
{
CCoeControl::MakeVisible( aVisible );
}
if (Cba())
{
Cba()->UpdateCbaLabels( aVisible );
}
}
EXPORT_C void CEikScrollBar::SetContainingCba(CEikCba* aCba)
{
// This is technically a compatability break, because it means that SetContainingCba
// must only be called after ConstructL(). Fortunately, the only place where this API
// should ever be called is already correct.
__ASSERT_ALWAYS(iExtension, Panic(EEikPanicScrollBarExtensionNotCreated));
iExtension->SetContainingCba(aCba);
}
CEikCba* CEikScrollBar::Cba() const
{
if (iExtension)
return iExtension->Cba();
else
return NULL;
}
void CEikScrollBar::AddExternalFrameL(CEikScrollBarFrame* aFrame)
{
__ASSERT_ALWAYS(iExtension, Panic(EEikPanicScrollBarExtensionNotCreated));
iExtension->AddExternalFrameL(aFrame);
}
void CEikScrollBar::RemoveExternalFrame(CEikScrollBarFrame* aFrame)
{
__ASSERT_ALWAYS(iExtension, Panic(EEikPanicScrollBarExtensionNotCreated));
iExtension->RemoveExternalFrame(aFrame);
}
void CEikScrollBar::DisconnectExternalFrames()
{
if (iExtension)
{
iExtension->DisconnectExternalFrames();
}
}
CEikScrollBar::TScrollBarType CEikScrollBar::ScrollBarType()
{
if (iExtension)
{
return static_cast<CEikScrollBar::TScrollBarType> (iExtension->ScrollBarType());
}
return CEikScrollBar::TScrollBarType(ENormalScrollBar);
}
// ----------------------------------------------------------------------------
// CEikScrollBar::SetScrollBarObserver
//
// Sets scroll bar observer. This enables changing of the observer also after the
// scroll bar has been constructed.
// ----------------------------------------------------------------------------
//
void CEikScrollBar::SetScrollBarObserver(MEikScrollBarObserver* aScrollBarObserver)
{
if( !AknLayoutUtils::PenEnabled() )
{
return;
}
if(ScrollBarType() == CEikScrollBar::EDoubleSpan)
{
CAknDoubleSpanScrollBarExtension* extension = static_cast<CAknDoubleSpanScrollBarExtension*> (iExtension);
extension->SetScrollBarObserver(aScrollBarObserver);
}
else
{
CEikScrollBarExtension* extension = static_cast<CEikScrollBarExtension*> (iExtension);
extension->SetScrollBarObserver(aScrollBarObserver);
}
}
//
// class CEikScrollBarExtension
//
CEikScrollBarExtension::CEikScrollBarExtension(CEikScrollBar* aParent)
: iExternalFrames(1)
{
iParent=aParent;
}
CEikScrollBarExtension::~CEikScrollBarExtension()
{
}
void CEikScrollBarExtension::SetLengthL(TInt /*aLength*/)
{
}
void CEikScrollBarExtension::SetModelL(const TEikScrollBarModel* /*aModel*/)
{
}
void CEikScrollBarExtension::SetModel(const TEikScrollBarModel* /*aModel*/)
{
}
void CEikScrollBarExtension::SetLengthAndModelL(TInt /*aLength*/,const TEikScrollBarModel* /*aModel*/)
{
}
void CEikScrollBarExtension::SetModelThumbPosition(TInt /*aThumbPos*/)
{
}
void CEikScrollBarExtension::SetFocusPosToThumbPos(TInt /*aFocusPosition*/)
{
}
TInt CEikScrollBarExtension::ThumbPosition() const
{
return(iParent->iModel.iThumbPosition);
}
TInt CEikScrollBarExtension::ScrollBarBreadth() const
{
if (iParent->iOrientation==CEikScrollBar::EHorizontal)
return iParent->iSize.iHeight;
return iParent->iSize.iWidth;
}
void CEikScrollBarExtension::SetDecreaseButtonsDimmed(TBool /*aDimmed*/)
{
}
void CEikScrollBarExtension::SetIncreaseButtonsDimmed(TBool /*aDimmed*/)
{
}
void CEikScrollBarExtension::SetAllButtonsDimmed(TBool /*aDimmed*/)
{
}
void CEikScrollBarExtension::SetContainingCba(CEikCba* aCba)
{
iCba = aCba;
}
TInt CEikScrollBarExtension::ScrollBarType()
{
return CEikScrollBar::EArrowHead;
}
void CEikScrollBarExtension::DoSetModel(const TEikScrollBarModel* aModel)
{
iParent->iModel=(*aModel);
iParent->iModel.CheckBounds();
TInt focusPosition=iParent->iModel.iThumbPosition;
if ((focusPosition!=-1) && iParent && iParent->iButtons.iIncreaseNudge && iParent->iButtons.iDecreaseNudge)
{
iParent->iButtons.iIncreaseNudge->SetPosition(focusPosition, iParent->iModel.iScrollSpan);
iParent->iButtons.iDecreaseNudge->SetPosition(focusPosition, iParent->iModel.iScrollSpan);
}
}
CEikCba* CEikScrollBarExtension::Cba() const
{
return iCba;
}
void CEikScrollBarExtension::AddExternalFrameL(CEikScrollBarFrame* aFrame)
{
iExternalFrames.AppendL(aFrame);
}
void CEikScrollBarExtension::RemoveExternalFrame(CEikScrollBarFrame* aFrame)
{
TInt count = iExternalFrames.Count();
for (TInt ii=count-1; ii>=0; ii--)
{
if (iExternalFrames[ii] == aFrame)
{
iExternalFrames[ii]->DisconnectExternalScrollBar(iParent);
iExternalFrames.Delete(ii);
}
}
}
void CEikScrollBarExtension::DisconnectExternalFrames()
{
TInt count = iExternalFrames.Count();
for (TInt ii=count-1; ii>=0; ii--)
{
iExternalFrames[ii]->DisconnectExternalScrollBar(iParent);
}
iExternalFrames.Reset();
}
void CEikScrollBarExtension::CreateRequiredComponentsL()
{
TBool horiz=(iParent->iOrientation==CEikScrollBar::EHorizontal);
iParent->CreateButtonL(iParent->iButtons.iDecreaseNudge,horiz ? CAknScrollButton::ENudgeLeft : CAknScrollButton::ENudgeUp);
iParent->CreateButtonL(iParent->iButtons.iIncreaseNudge,horiz ? CAknScrollButton::ENudgeRight : CAknScrollButton::ENudgeDown);
}
void CEikScrollBarExtension::DestroyButton(CAknScrollButton*& /*aButton*/)
{
}
void CEikScrollBarExtension::SetButtonPositionL(CAknScrollButton* /*aButton*/)
{
}
void CEikScrollBarExtension::SetScrollBarObserver(MEikScrollBarObserver* aScrollBarObserver)
{
iScrollBarObserver = aScrollBarObserver;
}
MEikScrollBarObserver* CEikScrollBarExtension::ScrollBarObserver()
{
return iScrollBarObserver;
}
TBool CEikScrollBarExtension::HasModelChanged(const TEikScrollBarModel* /*aModel*/)
{
return EFalse;
}
TInt CEikScrollBarExtension::Reserved_1(){return 0;};
TInt CEikScrollBarExtension::Reserved_2(){return 0;};
//
// class CEikArrowHeadScrollBar
//
EXPORT_C CEikArrowHeadScrollBar::CEikArrowHeadScrollBar(CCoeControl* aParentWindow)
: iParentControl(aParentWindow)
{
AKNTASHOOK_ADD( this, "CEikArrowHeadScrollBar" );
}
EXPORT_C CEikArrowHeadScrollBar::~CEikArrowHeadScrollBar()
{
AKNTASHOOK_REMOVE();
}
EXPORT_C void CEikArrowHeadScrollBar::ConstructL(MEikScrollBarObserver* aScrollBarObserver,const CCoeControl* aParent,
TOrientation aOrientation,TInt aLength,TInt aScrollBarFlags)
// Second-phase construction
{
iExtension = new(ELeave) CEikScrollBarExtension(this);
CEikScrollBar::ConstructL(aScrollBarObserver,aParent,aOrientation,aLength,aScrollBarFlags);
}
void CEikArrowHeadScrollBar::CreateButtonL(CAknScrollButton*& aButton,CAknScrollButton::TType aType)
// Create the appropriate button
{
if (aButton)
return;
CAknScrollButton* button=CAknScrollButton::NewL(aType);
CleanupStack::PushL(button);
button->CreateWindowOnlyForArrowsL(iParentControl);
button->SetObserver((MCoeControlObserver*)this);
SetButtonPositionL(button);
button->SetTypeOfScrollBarUsingButton(CAknScrollButton::EArrowHead);
CleanupStack::Pop(); // button
aButton=button;
}
void CEikArrowHeadScrollBar::SetButtonPositionL(CAknScrollButton* aButton)
{
TInt index = aButton->Type()==CAknScrollButton::ENudgeDown ? 1 : 0;
TAknWindowLineLayout lay( AKN_LAYOUT_TABLE_Control_pane_elements(index) );
TAknLayoutRect lr;
lr.LayoutRect( Rect(), lay );
TRect r( lr.Rect() );
aButton->SetExtent( r.iTl, TSize( Size().iWidth, r.Height() ) );
}
EXPORT_C void CEikArrowHeadScrollBar::HandlePointerEventL(const TPointerEvent& aPointerEvent)
{
CEikScrollBar::HandlePointerEventL(aPointerEvent);
}
EXPORT_C void* CEikArrowHeadScrollBar::ExtensionInterface( TUid /*aInterface*/ )
{
return NULL;
}
//
// class CAknDoubleSpanScrollBar
//
EXPORT_C CAknDoubleSpanScrollBar::CAknDoubleSpanScrollBar(CCoeControl* aParentWindow)
: iParentControl(aParentWindow)
{
AKNTASHOOK_ADD( this, "CAknDoubleSpanScrollBar" );
}
EXPORT_C CAknDoubleSpanScrollBar::~CAknDoubleSpanScrollBar()
{
AKNTASHOOK_REMOVE();
if ( iAvkonAppUiBase )
{
CAknPointerEventModifier* modifier = iAvkonAppUiBase->PointerEventModifier();
if ( modifier )
{
modifier->Pop( *this );
}
}
AknsUtils::DeregisterControlPosition( this );
}
EXPORT_C void CAknDoubleSpanScrollBar::ConstructL(TBool aWindowOwning, MEikScrollBarObserver* aScrollBarObserver,const CCoeControl* aParent,
TOrientation aOrientation,TInt /*aLength*/,TInt aScrollBarFlags )
{
iExtension = new(ELeave) CAknDoubleSpanScrollBarExtension(this);
CAknDoubleSpanScrollBarExtension* extension = static_cast<CAknDoubleSpanScrollBarExtension*> (iExtension);
extension->iScrollBarFlags = aScrollBarFlags;
extension->iExtensionType = ENormalExpandedTouchArea;
if ( AknLayoutUtils::PenEnabled() )
{
extension->SetScrollBarObserver(aScrollBarObserver); // sets also the owning observer
extension->iPopupController = CAknInfoPopupNoteController::NewL();
extension->iPopupController->SetTooltipModeL( ETrue );
extension->iPopupController->SetTimeDelayBeforeShow( 1 );
extension->iShowPopup = EFalse;
}
if (aWindowOwning)
{
CreateWindowL(aParent);
EnableWindowTransparency();
Window().SetPointerGrab( ETrue );
EnableDragEvents();
}
else if(aParent)
{
SetContainerWindowL(*aParent);
}
else
{
User::Leave(KErrArgument);
}
if( aParent )
SetObserver(aParent->Observer());
else
SetObserver(NULL);
iOrientation=aOrientation;
CreateRequiredComponentsL();
SetComponentsToInheritVisibility(ETrue);
MakeVisible(EFalse);
ActivateL();
}
EXPORT_C void CAknDoubleSpanScrollBar::ConstructL(MEikScrollBarObserver* aScrollBarObserver,const CCoeControl* aParent,
TOrientation aOrientation,TInt aLength,TInt aScrollBarFlags)
// Second-phase construction, overides method from CEikScrollBar
{
ConstructL(ETrue, aScrollBarObserver, aParent, aOrientation, aLength, aScrollBarFlags);
}
// ----------------------------------------------------------------------------
// CAknDoubleSpanScrollBar::CreateButtonL
//
// Creates buttons for double span scrollbar when __PEN_SUPPORT is enabled
// ----------------------------------------------------------------------------
//
void CAknDoubleSpanScrollBar::CreateButtonL(CAknScrollButton*& aButton, CAknScrollButton::TType aType)
// Create the appropriate button
{
if( !AknLayoutUtils::PenEnabled() )
{
// No buttons exist in this type of scrollbar
return;
}
if (aButton)
{
return;
}
CAknScrollButton* button = CAknScrollButton::NewL(aType, CAknScrollButton::ENormal);
CleanupStack::PushL(button);
if ( OwnsWindow() && AknLayoutUtils::PenEnabled() )
{
button->CreateWindowOnlyForArrowsL( this );
}
button->SetContainerWindowL( *this );
CleanupStack::Pop(); // button
aButton = button;
}
// ----------------------------------------------------------------------------
// CAknDoubleSpanScrollBar::SetButtonPositionL
//
// Sets button position when AknLayoutUtils::PenEnabled() returns ETrue
// This function is called from CAknDoubleSpanScrollBar::SizeChanged() function
// The button rectangle should be set in this function according to LAF spec
// ----------------------------------------------------------------------------
//
void CAknDoubleSpanScrollBar::SetButtonPositionL(CAknScrollButton* aButton)
{
if( !AknLayoutUtils::PenEnabled() )
{
// No buttons exist in this type of scrollbar
return;
}
if ( aButton )
{
if( iExtension )
{
TAknWindowComponentLayout buttonLayout;
TAknLayoutRect buttonRect;
switch(aButton->Type())
{
case CAknScrollButton::ENudgeUp:
buttonLayout = AknLayoutScalable_Avkon::scroll_sc2_up_pane( 1 );
buttonRect.LayoutRect( Rect(), buttonLayout.LayoutLine() );
aButton->SetRect( buttonRect.Rect() );
break;
case CAknScrollButton::ENudgeDown:
buttonLayout = AknLayoutScalable_Avkon::scroll_sc2_down_pane( 1 );
buttonRect.LayoutRect( Rect(), buttonLayout.LayoutLine() );
aButton->SetRect( buttonRect.Rect() );
break;
case CAknScrollButton::ENudgeLeft:
buttonLayout = AknLayoutScalable_Avkon::scroll_sc2_left_pane();
buttonRect.LayoutRect( Rect(), buttonLayout.LayoutLine() );
aButton->SetRect( buttonRect.Rect() );
break;
case CAknScrollButton::ENudgeRight:
buttonLayout = AknLayoutScalable_Avkon::scroll_sc2_right_pane();
buttonRect.LayoutRect( Rect(), buttonLayout.LayoutLine() );
aButton->SetRect( buttonRect.Rect() );
break;
default:
break;
}
}
}
}
EXPORT_C void CAknDoubleSpanScrollBar::MakeVisible(TBool aVisible)
{
CAknPointerEventModifier* modifier = iAvkonAppUiBase ? iAvkonAppUiBase->PointerEventModifier() : NULL;
if ( modifier )
{
CAknDoubleSpanScrollBarExtension* extension = static_cast<CAknDoubleSpanScrollBarExtension*> (iExtension);
if ( aVisible && (extension->iScrollIndicator->ScrollSpan() > 0) && !( extension->iExtensionType & ENoExpandedTouchArea ) )
{
modifier->Push( *this, ExtensionArea() );
}
else
{
modifier->Pop( *this );
}
}
CCoeControl::MakeVisible(aVisible);
}
EXPORT_C TInt CAknDoubleSpanScrollBar::CountComponentControls() const
{
TInt controlCount = 0;
if (iExtension)
{
CAknDoubleSpanScrollBarExtension* extension = static_cast<CAknDoubleSpanScrollBarExtension*> (iExtension);
if (extension->iScrollIndicator)
{
controlCount = 1;
}
}
if(AknLayoutUtils::PenEnabled())
{
if(iButtons.iIncreaseNudge)
{
controlCount++;
}
if(iButtons.iDecreaseNudge)
{
controlCount++;
}
}
return controlCount;
}
EXPORT_C CCoeControl* CAknDoubleSpanScrollBar::ComponentControl(TInt aIndex) const
{
CCoeControl* control = NULL;
if (aIndex==0 && iExtension)
{
CAknDoubleSpanScrollBarExtension* extension = static_cast<CAknDoubleSpanScrollBarExtension*> (iExtension);
control = extension->iScrollIndicator;
}
if(AknLayoutUtils::PenEnabled())
{
if(aIndex == 1)
{
control = iButtons.iIncreaseNudge;
}
else if(aIndex == 2)
{
control = iButtons.iDecreaseNudge;
}
}
return control;
}
EXPORT_C void CAknDoubleSpanScrollBar::SizeChanged()
{
CAknPointerEventModifier* modifier = iAvkonAppUiBase ? iAvkonAppUiBase->PointerEventModifier() : NULL;
if (iExtension)
{
CAknDoubleSpanScrollBarExtension* extension = static_cast<CAknDoubleSpanScrollBarExtension*> (iExtension);
if ( modifier && IsVisible() && !( extension->iExtensionType & ENoExpandedTouchArea ) )
{
modifier->Update( *this, ExtensionArea() );
}
}
else
{
if ( modifier && IsVisible() )
{
modifier->Update( *this, ExtensionArea() );
}
}
AknsUtils::RegisterControlPosition( this );
if (iExtension)
{
CAknDoubleSpanScrollBarExtension* extension = static_cast<CAknDoubleSpanScrollBarExtension*> (iExtension);
CAknDoubleSpanScrollIndicator* indicator = extension->iScrollIndicator;
// set indicator size to same as the whole scrollbar.
if (indicator)
{
TAknWindowComponentLayout combinedRect;
TInt variety = 0;
TInt scVariety = 0;
// No pen check as the layout for the non-pen is not taken from layout data
// if in future made so, this must be changed to support also non-pen situations
if( AknLayoutUtils::PenEnabled() )
{
if ( iOrientation == EHorizontal)
{
variety = 2;
scVariety = 1;
}
else
{
variety = 1;
}
}
combinedRect = TAknWindowComponentLayout::Compose( AknLayoutScalable_Avkon::scroll_pane( scVariety ),
AknLayoutScalable_Avkon::bg_scroll_pane( variety ) );
TAknLayoutRect indicatorRect;
if (OwnsWindow())
{
if( AknLayoutUtils::PenEnabled() &&
( extension->iScrollBarFlags & EEnableNudgeButtons ) )
{
// when the pen support is enabled, the space for arrows must be reserved.
indicatorRect.LayoutRect( Rect(), combinedRect.LayoutLine() );
indicator->SetRect( indicatorRect.Rect() );
}
else
{
indicator->SetExtent(TPoint(0,0),Size());
}
if (indicator->TransparentBackground())
{
// This will refresh the transparency masks
SetTransparentBackground(ETrue);
}
}
else
{
if( AknLayoutUtils::PenEnabled() &&
( extension->iScrollBarFlags & EEnableNudgeButtons ) )
{
// when the pen support is enabled, the space for arrows must be reserved.
TRect rect( Position(), Size() );
indicatorRect.LayoutRect( rect, combinedRect.LayoutLine() );
indicator->SetRect( indicatorRect.Rect() );
}
else
{
indicator->SetExtent(Position(),Size());
}
}
}
if(AknLayoutUtils::PenEnabled())
{
if ( !iButtons.iIncreaseNudge || !iButtons.iDecreaseNudge )
{
TRAP_IGNORE( CreateRequiredComponentsL() );
}
// Set scroll button positions
TRAP_IGNORE( SetButtonPositionL( iButtons.iIncreaseNudge ) );
TRAP_IGNORE( SetButtonPositionL( iButtons.iDecreaseNudge ) );
}
}
}
// ----------------------------------------------------------------------------
// CAknDoubleSpanScrollBar::HandlePointerEventL
//
// Handles pointer events.
// ----------------------------------------------------------------------------
//
EXPORT_C void CAknDoubleSpanScrollBar::HandlePointerEventL(const TPointerEvent& aPointerEvent)
{
if( !AknLayoutUtils::PenEnabled() || !iExtension)
{
return;
}
if ( aPointerEvent.iType == TPointerEvent::EButton1Down && GrabbingComponent() != this && OwnsWindow() )
{
ClaimPointerGrab( EFalse );
}
CAknDoubleSpanScrollBarExtension* extension =
static_cast<CAknDoubleSpanScrollBarExtension*> (iExtension);
CAknDoubleSpanScrollIndicator* indicator = extension->iScrollIndicator;
RDrawableWindow* pointerWindow = &Window();
TRect rect(indicator->Rect());
// scale the pointer event position relative to indicator rect
// this has effect only if the scroll bar is not window owning
TPoint eventPos(aPointerEvent.iPosition - rect.iTl);
// use x or y values depending on orientation
TInt position(eventPos.iY);
TInt scrollSpanPix(rect.Height());
if(iOrientation == EHorizontal)
{
position = eventPos.iX;
scrollSpanPix = rect.Width();
}
// get current values from the indicator
TInt scrollSpan(indicator->ScrollSpan());
TInt thumbSpan(indicator->WindowSize());
TInt thumbPosition(indicator->FocusPosition());
TInt thumbSpanPix = indicator->GetCurrentThumbSpanInPixels();
TInt thumbPositionPix = indicator->GetCurrentThumbPositionInPixels();
// clear the pointer down info on pen up and hide info popup
TInt lastPointerDownOn = extension->iPointerDownOn;
// The real span area available (as pixels)
scrollSpanPix -= thumbSpanPix;
// touch release on thumb
TBool thumbPressed =
( position < (thumbPositionPix + thumbSpanPix)
&& position > thumbPositionPix );
if ( thumbPressed &&
aPointerEvent.iType == TPointerEvent::EButton1Up &&
thumbSpan < scrollSpan )
{
MTouchFeedback* feedback = MTouchFeedback::Instance();
CCoeControl* parent = Parent();
TBool feedbackEnabled = !IsDimmed() && IsVisible();
if (parent && feedbackEnabled)
{
// check the same for the parent
feedbackEnabled = !parent->IsDimmed() && parent->IsVisible();
}
if ( feedback && feedbackEnabled )
{
feedback->InstantFeedback( this,
ETouchFeedbackSlider,
ETouchFeedbackVibra,
aPointerEvent );
}
}
if ( aPointerEvent.iType == TPointerEvent::EButton1Up )
{
extension->iPointerDownOn = CEikScrollBar::ENone;
// Highlight off always when the pointer is lifted
indicator->SetHandleHighlight( EFalse );
indicator->DrawDeferred();
indicator->SetBackgroudHighlight( EFalse );
if ( extension->iPopupController )
{
extension->iPopupController->HideInfoPopupNote();
extension->iShowPopup = EFalse;
}
}
// check that scroll bar is useful
if (thumbSpan < scrollSpan)
{
// check where the pointer down occured
if(aPointerEvent.iType == TPointerEvent::EButton1Down )
{
indicator->SetBackgroudHighlight( ETrue );
extension->iPointerDownPosition = position;
if(iButtons.iIncreaseNudge &&
iButtons.iIncreaseNudge->Rect().Contains(aPointerEvent.iPosition))
{
extension->iPointerDownOn = CEikScrollBar::EIncreaseNudgeButton;
}
else if(iButtons.iDecreaseNudge &&
iButtons.iDecreaseNudge->Rect().Contains(aPointerEvent.iPosition))
{
extension->iPointerDownOn = CEikScrollBar::EDecreaseNudgeButton;
}
else if (position < thumbPositionPix)
{
extension->iPointerDownOn = CEikScrollBar::EDecreaseShaft;
}
else if (position < (thumbPositionPix + thumbSpanPix))
{
extension->iDragged = EFalse;
extension->iPointerDownOn = CEikScrollBar::EThumb;
extension->iPointerOffsetFromThumb = position - thumbPositionPix;
indicator->SetHandleHighlight( ETrue );
indicator->DrawDeferred();
}
else
{
extension->iPointerDownOn = CEikScrollBar::EIncreaseShaft;
}
}
// respond to the pointer event
switch(extension->iPointerDownOn)
{
case CEikScrollBar::EDecreaseShaft:
case CEikScrollBar::EIncreaseShaft:
{
TEikScrollEvent event = EEikScrollPageUp;
if(aPointerEvent.iType == TPointerEvent::EButton1Down ||
aPointerEvent.iType == TPointerEvent::EButtonRepeat)
{
if(extension->iPointerDownOn == CEikScrollBar::EDecreaseShaft)
{
event = iOrientation==EHorizontal ? EEikScrollPageLeft : EEikScrollPageUp;
thumbPosition -= thumbSpan;
thumbPosition = Max(0, thumbPosition);
TInt prevPosValue = extension->ThumbPosition();
// This will update the thumb's pixel extent, used
// below
extension->SetModelThumbPosition(thumbPosition);
indicator->SetIndicatorValues(scrollSpan, thumbPosition, thumbSpan, 0, 0);
TInt afterPosValue = extension->ThumbPosition();
if (prevPosValue != afterPosValue)
{
MTouchFeedback* feedback = MTouchFeedback::Instance();
CCoeControl* parent = Parent();
TBool feedbackEnabled = !IsDimmed() && IsVisible();
if (parent && feedbackEnabled)
{
// check the same for the parent
feedbackEnabled = !parent->IsDimmed() && parent->IsVisible();
}
if ( feedback && feedbackEnabled )
{
feedback->InstantFeedback( this, ETouchFeedbackSlider, aPointerEvent );
}
}
// request pointer repeat until the thumb reaches the pen down position
TInt newThumbPosPix = indicator->GetCurrentThumbPositionInPixels();
if(position < newThumbPosPix)
{
TRect ignoreRect(rect);
TRect rt = ExtensionArea();
if(iOrientation == EVertical)
{
ignoreRect.iTl = TPoint(rt.iTl.iX, rect.iTl.iY);
ignoreRect.iBr = TPoint(ignoreRect.iBr.iX, newThumbPosPix + rect.iTl.iY);
}
else
{
ignoreRect.iTl = TPoint(rect.iTl.iX, rt.iTl.iY);
ignoreRect.iBr = TPoint(newThumbPosPix, rt.iBr.iY);
}
// repeat until thumb reaches the stylus down position
pointerWindow->RequestPointerRepeatEvent(KScrollRepeatTimeout, ignoreRect);
}
}
else
{
event = iOrientation==EHorizontal ? EEikScrollPageRight : EEikScrollPageDown;
thumbPosition += thumbSpan;
thumbPosition = Min((scrollSpan - thumbSpan), thumbPosition);
TInt prevPosValue = extension->ThumbPosition();
extension->SetModelThumbPosition(thumbPosition);
indicator->SetIndicatorValues(scrollSpan, thumbPosition, thumbSpan, 0, 0);
TInt afterPosValue = extension->ThumbPosition();
if (prevPosValue != afterPosValue)
{
MTouchFeedback* feedback = MTouchFeedback::Instance();
CCoeControl* parent = Parent();
TBool feedbackEnabled = !IsDimmed() && IsVisible();
if (parent && feedbackEnabled)
{
// check the same for the parent
feedbackEnabled = !parent->IsDimmed() && parent->IsVisible();
}
if ( feedback && feedbackEnabled )
{
feedback->InstantFeedback( this, ETouchFeedbackSlider, aPointerEvent );
}
}
// request pointer repeat until the thumb reaches the pen down position
TInt newThumbPosPix = indicator->GetCurrentThumbPositionInPixels();
newThumbPosPix += thumbSpanPix;
if(position > newThumbPosPix )
{
TRect ignoreRect(rect);
TRect rt = ExtensionArea();
if(iOrientation == EVertical)
{
ignoreRect.iTl = TPoint(rt.iTl.iX, newThumbPosPix + rect.iTl.iY);
}
else
{
ignoreRect.iTl = TPoint(newThumbPosPix, rt.iTl.iY);
}
// repeat until thumb reaches the stylus down position
pointerWindow->RequestPointerRepeatEvent(KScrollRepeatTimeout, ignoreRect);
}
}
if(indicator->DrawBackgroundState())
indicator->DrawNow();
else
indicator->DrawDeferred();
if(extension->ScrollBarObserver())
{
extension->ScrollBarObserver()->HandleScrollEventL(this, event);
}
}
}
break;
case CEikScrollBar::EThumb:
if( aPointerEvent.iType == TPointerEvent::EButton1Down )
{
MTouchFeedback* feedback = MTouchFeedback::Instance();
if ( feedback )
{
TTouchFeedbackType fbType = TTouchFeedbackType(
ETouchFeedbackAudio |
ETouchFeedbackVibra );
feedback->InstantFeedback( this, ETouchFeedbackSlider, fbType, aPointerEvent );
}
}
if( aPointerEvent.iType == TPointerEvent::EDrag
|| aPointerEvent.iType == TPointerEvent::EButtonRepeat )
{
// performace improving. Too many drag event received, handling every single event
// will use too much CPU time.
TTime now;
now.HomeTime();
if ( extension->iDragged &&
now.MicroSecondsFrom( extension->iLastDrag )
< KScrollDragTimeout )
{
break; // ignore drag for this time
}
extension->iDragged = ETrue; // after this time, iLastDragged has value.
extension->iLastDrag = now;
thumbPositionPix = position - extension->iPointerOffsetFromThumb;
TInt oldPosition = thumbPosition;
TReal newPosition = thumbPositionPix * ( scrollSpan - thumbSpan ) / (TReal)scrollSpanPix;
thumbPosition = newPosition;
// round the value to the nearest possible position
if( TInt(newPosition * 2) >= ((thumbPosition * 2) + 1 ))
{
++thumbPosition;
}
// enforce limits
thumbPosition = Max(0, thumbPosition);
thumbPosition = Min((scrollSpan - thumbSpan), thumbPosition);
if(thumbPosition != oldPosition)
{
extension->SetModelThumbPosition(thumbPosition);
indicator->SetIndicatorValues(scrollSpan, thumbPosition, thumbSpan, 0, 0);
if(indicator->DrawBackgroundState())
indicator->DrawNow();
else
indicator->DrawDeferred();
if(extension->ScrollBarObserver())
{
extension->ScrollBarObserver()->HandleScrollEventL(
this,
iOrientation==EHorizontal ? EEikScrollThumbDragHoriz : EEikScrollThumbDragVert);
}
}
// Show popup info
if ( extension->iShowPopup && extension->iPopupController )
{
TPoint infoPoint = PositionRelativeToScreen();
if ( iOrientation == EVertical )
{
if ( AknLayoutUtils::LayoutMirrored() )
{
infoPoint.iX += Rect().Width();
infoPoint.iY += aPointerEvent.iPosition.iY;
extension->iPopupController->SetPositionAndAlignment (
infoPoint, EHLeftVCenter );
}
else
{
infoPoint.iY += aPointerEvent.iPosition.iY;
extension->iPopupController->SetPositionAndAlignment (
infoPoint, EHRightVCenter );
}
}
else if ( iOrientation == EHorizontal )
{
infoPoint.iX += aPointerEvent.iPosition.iX;
extension->iPopupController->SetPositionAndAlignment(
infoPoint, EHCenterVBottom );
}
extension->iPopupController->ShowInfoPopupNote();
extension->iShowPopup = EFalse;
}
}
break;
case CEikScrollBar::ENone:
if(lastPointerDownOn == CEikScrollBar::EThumb)
{
if(extension->ScrollBarObserver())
{
extension->ScrollBarObserver()->HandleScrollEventL(
this,
iOrientation==EHorizontal ? EEikScrollThumbReleaseHoriz : EEikScrollThumbReleaseVert);
}
}
break;
case CEikScrollBar::EIncreaseNudgeButton:
// handle increase scroll button press (right or down button)
if(aPointerEvent.iType == TPointerEvent::EButton1Down ||
aPointerEvent.iType == TPointerEvent::EButtonRepeat)
{
TInt oldPosition = thumbPosition;
thumbPosition++;
thumbPosition = Min((scrollSpan - thumbSpan), thumbPosition);
if(oldPosition != thumbPosition)
{
// Note: Depending on layout and style the nudge
// button may be obsolete.
// Sensitive feedback given for each "nudge"
MTouchFeedback* feedback = MTouchFeedback::Instance();
if ( feedback )
{
feedback->InstantFeedback ( this, ETouchFeedbackSlider, aPointerEvent );
}
extension->SetModelThumbPosition(thumbPosition);
indicator->SetIndicatorValues(scrollSpan, thumbPosition, thumbSpan, 0, 0);
if(indicator->DrawBackgroundState())
indicator->DrawNow();
else
indicator->DrawDeferred();
}
// even if the thumb position did not change (thumb has reached its last
// possible position), we must send the event
// to the observer, so that it can implement the looping scrolling if necessary
if(extension->ScrollBarObserver())
{
extension->ScrollBarObserver()->HandleScrollEventL(
this,
iOrientation==EHorizontal ? EEikScrollRight : EEikScrollDown);
}
// repeat untill stylus is lifted or dragged outside the button
TRect nudgeRect( iButtons.iIncreaseNudge->Rect() );
pointerWindow->RequestPointerRepeatEvent(KScrollRepeatTimeout, nudgeRect );
}
break;
case CEikScrollBar::EDecreaseNudgeButton:
// handle decrease scroll button press (left or up button)
if(aPointerEvent.iType == TPointerEvent::EButton1Down ||
aPointerEvent.iType == TPointerEvent::EButtonRepeat)
{
TInt oldPosition = thumbPosition;
thumbPosition--;
thumbPosition = Max(0, thumbPosition);
if(oldPosition != thumbPosition)
{
// Note: Depending on layout and style the nudge
// button may be obsolete.
// Sensitive feedback given for each "nudge"
MTouchFeedback* feedback = MTouchFeedback::Instance();
if ( feedback )
{
feedback->InstantFeedback ( this, ETouchFeedbackSlider, aPointerEvent );
}
extension->SetModelThumbPosition(thumbPosition);
indicator->SetIndicatorValues(scrollSpan, thumbPosition, thumbSpan, 0, 0);
if(indicator->DrawBackgroundState())
indicator->DrawNow();
else
indicator->DrawDeferred();
}
// even if the thumb position did not change (thumb has reached its first
// possible position), we must send the event
// to the observer, so that it can implement the looping scrolling if necessary
if(extension->ScrollBarObserver())
{
extension->ScrollBarObserver()->HandleScrollEventL(
this,
iOrientation==EHorizontal ? EEikScrollLeft : EEikScrollUp);
}
// repeat untill stylus is lifted or dragged outside the button
TRect nudgeRect( iButtons.iDecreaseNudge->Rect() );
pointerWindow->RequestPointerRepeatEvent(KScrollRepeatTimeout, nudgeRect );
}
break;
default:
break;
} // end: of switch
} // end of: if (thumbSpan < scrollSpan)
}
EXPORT_C void* CAknDoubleSpanScrollBar::ExtensionInterface( TUid /*aInterface*/ )
{
return NULL;
}
EXPORT_C void CAknDoubleSpanScrollBar::SetFixedLayoutRect(TRect aScrollBarRect)
{
if (iExtension)
{
CAknDoubleSpanScrollBarExtension* extension = static_cast<CAknDoubleSpanScrollBarExtension*> (iExtension);
extension->iFixedLayoutRect = aScrollBarRect;
SetRect(aScrollBarRect);
}
}
EXPORT_C void CAknDoubleSpanScrollBar::SetScrollPopupInfoTextL( const TDesC& aText )
{
if ( !AknLayoutUtils::PenEnabled() )
{
return;
}
if ( iExtension )
{
CAknDoubleSpanScrollBarExtension* extension = static_cast<CAknDoubleSpanScrollBarExtension*> (iExtension);
if ( extension->iPopupController )
{
if ( aText.Length() > 0 )
{
extension->iPopupController->SetTextL( aText );
extension->iShowPopup = ETrue;
}
else
{
extension->iPopupController->HideInfoPopupNote();
extension->iShowPopup = EFalse;
}
}
}
}
TRect CAknDoubleSpanScrollBar::FixedLayoutRect()
{
TRect fixedLayoutRect;
if (iExtension)
{
CAknDoubleSpanScrollBarExtension* extension = static_cast<CAknDoubleSpanScrollBarExtension*> (iExtension);
fixedLayoutRect = extension->iFixedLayoutRect;
}
return fixedLayoutRect;
}
void CAknDoubleSpanScrollBar::SetTransparentBackground(TBool aTransparentBackground)
{
// In transparency-enabled builds, consider making this function
// act as if DrawBackground( EFalse ) was called..
TBool transparencyIsSupported = EFalse; // Transparent windows are not supported for now
if (iExtension && OwnsWindow() && transparencyIsSupported)
{
CAknDoubleSpanScrollBarExtension* extension = static_cast<CAknDoubleSpanScrollBarExtension*> (iExtension);
CAknDoubleSpanScrollIndicator* indicator = extension->iScrollIndicator;
if (aTransparentBackground)
{
// removed old transparency related code
}
else
{
Window().SetNonTransparent();
}
indicator->SetTransparentBackground(aTransparentBackground);
}
}
TBool CAknDoubleSpanScrollBar::DrawBackgroundState()
{
CAknDoubleSpanScrollBarExtension* extension = static_cast<CAknDoubleSpanScrollBarExtension*> (iExtension);
CAknDoubleSpanScrollIndicator* indicator = extension->iScrollIndicator;
return indicator->DrawBackgroundState();
}
void CAknDoubleSpanScrollBar::DrawBackground(TBool aDraw)
{
CAknDoubleSpanScrollBarExtension* extension = static_cast<CAknDoubleSpanScrollBarExtension*> (iExtension);
CAknDoubleSpanScrollIndicator* indicator = extension->iScrollIndicator;
indicator->SetDrawBackgroundState(aDraw);
}
// ---------------------------------------------------------------------------
// CAknDoubleSpanScrollBar::ResetPressedDownHighlight
// ---------------------------------------------------------------------------
//
void CAknDoubleSpanScrollBar::ResetPressedDownHighlight()
{
CAknDoubleSpanScrollBarExtension* extension =
static_cast<CAknDoubleSpanScrollBarExtension*>( iExtension );
CAknDoubleSpanScrollIndicator* indicator = extension->iScrollIndicator;
indicator->SetHandleHighlight( EFalse );
}
//
// class CAknDoubleSpanScrollBarExtension
//
CAknDoubleSpanScrollBarExtension::CAknDoubleSpanScrollBarExtension(CEikScrollBar* aParent)
: iExternalFrames(1), iActiveScheduledDraw(NULL)
{
iParent=aParent;
}
CAknDoubleSpanScrollBarExtension::~CAknDoubleSpanScrollBarExtension()
{
delete iScrollIndicator;
iScrollIndicator = NULL;
if ( iPopupController )
{
delete iPopupController;
iPopupController = NULL;
}
if(iActiveScheduledDraw && iActiveScheduledDraw->IsActive())
iActiveScheduledDraw->Cancel();
delete iActiveScheduledDraw;
}
void CAknDoubleSpanScrollBarExtension::SetLengthL(TInt /*aLength*/)
{
}
void CAknDoubleSpanScrollBarExtension::SetModelL(const TEikScrollBarModel* /*aModel*/)
{
}
void CAknDoubleSpanScrollBarExtension::SetModel(const TEikScrollBarModel* /*aModel*/)
{
}
void CAknDoubleSpanScrollBarExtension::SetLengthAndModelL(TInt /*aLength*/,const TEikScrollBarModel* /*aModel*/)
{
}
// ----------------------------------------------------------------------------
// CAknDoubleSpanScrollBarExtension::SetModelThumbPosition
// Sets the thumb position to the model. This function has to be used because
// CAknDoubleSpanScrollBar does not have direct access to the model.
// ----------------------------------------------------------------------------
//
void CAknDoubleSpanScrollBarExtension::SetModelThumbPosition(TInt aThumbPos)
{
if( !AknLayoutUtils::PenEnabled() )
{
return;
}
if (iParent->iModel.ScrollBarModelType() == TEikScrollBarModel::EAknDoubleSpanScrollBarModel)
{
static_cast <TAknDoubleSpanScrollBarModel*> (&iParent->iModel)->SetFocusPosition(aThumbPos);
}
else
{
// Incorrect model is used, but in most cases we can work with the TEikScrollBarModel model.
iParent->iModel.iThumbPosition = aThumbPos;
}
}
void CAknDoubleSpanScrollBarExtension::SetFocusPosToThumbPos(TInt /*aFocusPosition*/)
{
}
TInt CAknDoubleSpanScrollBarExtension::ThumbPosition() const
{
if (iParent->iModel.ScrollBarModelType() == TEikScrollBarModel::EAknDoubleSpanScrollBarModel)
{
if( AknLayoutUtils::PenEnabled() )
{
// it is more effective to cast the pointer and use it directly
// than creating a copy of the model just to return a value
return static_cast <TAknDoubleSpanScrollBarModel*> (&iParent->iModel)->FocusPosition();
}
else
{
TAknDoubleSpanScrollBarModel& model = static_cast <TAknDoubleSpanScrollBarModel&> (iParent->iModel);
return model.FocusPosition();
}
}
else
{
// Error. User of the API is perhaps assigning values directly to TEikScrollBarModel
// member variables which is not allowed with EAknDoubleSpanScrollBarModel.
// #ifdef _DEBUG
// RDebug::Print(_L("CAknDoubleSpanScrollBarExtension: Please, use TAknDoubleSpanScrollBarModel instead of TEikScrollBarModel"));
// #endif
// In most cases we can work with the TEikScrollBarModel model.
return iParent->iModel.iThumbPosition;
}
}
TInt CAknDoubleSpanScrollBarExtension::ScrollBarBreadth() const
{
if (iScrollIndicator)
return iScrollIndicator->IndicatorWidth();
else
return KAknDoubleSpanScrollBarWidth;
}
void CAknDoubleSpanScrollBarExtension::SetDecreaseButtonsDimmed(TBool /*aDimmed*/)
{
}
void CAknDoubleSpanScrollBarExtension::SetIncreaseButtonsDimmed(TBool /*aDimmed*/)
{
}
void CAknDoubleSpanScrollBarExtension::SetAllButtonsDimmed(TBool /*aDimmed*/)
{
}
void CAknDoubleSpanScrollBarExtension::SetContainingCba(CEikCba* /*aCba*/)
{
// Not needed in this type of scrollbar
}
TInt CAknDoubleSpanScrollBarExtension::ScrollBarType()
{
return CEikScrollBarFrame::EDoubleSpan;
}
void CAknDoubleSpanScrollBarExtension::DoSetModel(const TEikScrollBarModel* aModel)
{
iParent->iModel=(*aModel);
if (iScrollIndicator)
{
if (aModel->ScrollBarModelType() == TEikScrollBarModel::EAknDoubleSpanScrollBarModel)
{
const TAknDoubleSpanScrollBarModel* model = static_cast <const TAknDoubleSpanScrollBarModel*> (aModel);
iScrollIndicator->SetIndicatorValues(model->ScrollSpan(),
model->FocusPosition(),
model->WindowSize(),
model->FieldPosition(),
model->FieldSize());
}
else
{
// Error. User of the API is perhaps assigning values directly to TEikScrollBarModel
// member variables which is not allowed with TAknDoubleSpanScrollBarModel.
// #ifdef _DEBUG
// RDebug::Print(_L("CAknDoubleSpanScrollBarExtension: Please, use TAknDoubleSpanScrollBarModel instead of TEikScrollBarModel"));
// #endif
// In most cases we can work with the TEikScrollBarModel model.
iScrollIndicator->SetIndicatorValues(aModel->iScrollSpan,
aModel->iThumbPosition,
aModel->iThumbSpan,
0,
0);
}
if(iScrollIndicator->IsVisible())
{
if(iScrollIndicator->DrawBackgroundState() && !iParent->OwnsWindow())
{
if(HasModelChanged(aModel))
{
TInt err = KErrNone;
if(!iActiveScheduledDraw) // create if not initialized
TRAP(err, iActiveScheduledDraw = CIdle::NewL(EPriorityHigh));
if(!err && !iActiveScheduledDraw->IsActive())
iActiveScheduledDraw->Start(TCallBack(ScheduledDraw,this));
}
}
else
{
iParent->DrawDeferred();
}
}
}
}
TBool CAknDoubleSpanScrollBarExtension::HasModelChanged(const TEikScrollBarModel* aModel)
{
if(iPreviousModel.ScrollBarModelType() == TEikScrollBarModel::EAknDoubleSpanScrollBarModel &&
aModel->ScrollBarModelType() == TEikScrollBarModel::EAknDoubleSpanScrollBarModel)
{
TAknDoubleSpanScrollBarModel* previousModel = static_cast<TAknDoubleSpanScrollBarModel*> (&iPreviousModel);
const TAknDoubleSpanScrollBarModel* model = static_cast<const TAknDoubleSpanScrollBarModel*> (aModel);
if(previousModel->ScrollSpan() != model->ScrollSpan() ||
previousModel->FocusPosition() != model->FocusPosition() ||
previousModel->WindowSize() != model->WindowSize() ||
previousModel->FieldPosition() != model->FieldPosition() ||
previousModel->FieldSize() != model->FieldSize())
{
iPreviousModel = *aModel;
return ETrue;
}
}
else if(iPreviousModel.ScrollBarModelType() == TEikScrollBarModel::EEikScrollBarModel &&
aModel->ScrollBarModelType() == TEikScrollBarModel::EAknDoubleSpanScrollBarModel)
{
const TAknDoubleSpanScrollBarModel* model = static_cast<const TAknDoubleSpanScrollBarModel*> (aModel);
if(iPreviousModel.iScrollSpan != model->ScrollSpan() ||
iPreviousModel.iThumbPosition != model->FocusPosition() ||
iPreviousModel.iThumbSpan != model->WindowSize())
{
iPreviousModel = *aModel;
return ETrue;
}
}
else if(iPreviousModel.ScrollBarModelType() == TEikScrollBarModel::EAknDoubleSpanScrollBarModel &&
aModel->ScrollBarModelType() == TEikScrollBarModel::EEikScrollBarModel)
{
TAknDoubleSpanScrollBarModel* previousModel = static_cast<TAknDoubleSpanScrollBarModel*> (&iPreviousModel);
if(previousModel->ScrollSpan() != aModel->iScrollSpan ||
previousModel->FocusPosition() != aModel->iThumbPosition ||
previousModel->WindowSize() != aModel->iThumbSpan)
{
iPreviousModel = *aModel;
return ETrue;
}
}
else
{
if(iPreviousModel.iScrollSpan != aModel->iScrollSpan ||
iPreviousModel.iThumbPosition != aModel->iThumbPosition ||
iPreviousModel.iThumbSpan != aModel->iThumbSpan)
{
iPreviousModel = *aModel;
return ETrue;
}
}
iPreviousModel = *aModel;
return EFalse;
}
CEikCba* CAknDoubleSpanScrollBarExtension::Cba() const
{
return NULL; // Not needed in this type of scrollbar
}
void CAknDoubleSpanScrollBarExtension::AddExternalFrameL(CEikScrollBarFrame* aFrame)
{
iExternalFrames.AppendL(aFrame);
iScrollBarObserver = aFrame->ScrollBarFrameObserver();
}
void CAknDoubleSpanScrollBarExtension::RemoveExternalFrame(CEikScrollBarFrame* aFrame)
{
TInt count = iExternalFrames.Count();
for (TInt ii=count-1; ii>=0; ii--)
{
if (iExternalFrames[ii] == aFrame)
{
iExternalFrames[ii]->DisconnectExternalScrollBar(iParent);
iExternalFrames.Delete(ii);
}
}
count = iExternalFrames.Count();
if(count == 0) //no externally owned anymore
{
iScrollBarObserver = iOwningScrollBarObserver;
}
else // set the next external frame as observer
{
iScrollBarObserver = iExternalFrames[(count - 1)]->ScrollBarFrameObserver();
}
}
void CAknDoubleSpanScrollBarExtension::DisconnectExternalFrames()
{
TInt count = iExternalFrames.Count();
for (TInt ii=count-1; ii>=0; ii--)
{
iExternalFrames[ii]->DisconnectExternalScrollBar(iParent);
}
iExternalFrames.Reset();
}
void CAknDoubleSpanScrollBarExtension::CreateRequiredComponentsL()
{
if ( !iScrollIndicator )
{
iScrollIndicator = CAknDoubleSpanScrollIndicator::NewL( iParent->iOrientation );
iScrollIndicator->SetContainerWindowL( *iParent );
iScrollIndicator->SetRect( iParent->Rect() );
iScrollIndicator->SetComponentsToInheritVisibility(ETrue);
iScrollIndicator->SetAsWindowOwning( iParent->OwnsWindow() );
}
if ( AknLayoutUtils::PenEnabled() &&
( iScrollBarFlags & CEikScrollBar::EEnableNudgeButtons ) )
{
TBool horiz=(iParent->iOrientation == CEikScrollBar::EHorizontal);
if ( !iParent->iButtons.iDecreaseNudge )
{
iParent->CreateButtonL(iParent->iButtons.iDecreaseNudge,horiz ? CAknScrollButton::ENudgeLeft : CAknScrollButton::ENudgeUp);
}
if ( !iParent->iButtons.iIncreaseNudge )
{
iParent->CreateButtonL(iParent->iButtons.iIncreaseNudge,horiz ? CAknScrollButton::ENudgeRight : CAknScrollButton::ENudgeDown);
}
}
}
void CAknDoubleSpanScrollBarExtension::DestroyButton(CAknScrollButton*& /*aButton*/)
{
}
void CAknDoubleSpanScrollBarExtension::SetButtonPositionL(CAknScrollButton* /*aButton*/)
{
}
void CAknDoubleSpanScrollBarExtension::SetScrollBarObserver(MEikScrollBarObserver* aScrollBarObserver)
{
iScrollBarObserver = aScrollBarObserver;
if(iExternalFrames.Count() == 0)
{
iOwningScrollBarObserver = aScrollBarObserver;
}
}
MEikScrollBarObserver* CAknDoubleSpanScrollBarExtension::ScrollBarObserver()
{
return iScrollBarObserver;
}
TInt CAknDoubleSpanScrollBarExtension::ScheduledDraw( TAny* aThis )
{
static_cast<CAknDoubleSpanScrollBarExtension*>( aThis )->DoScheduledDraw();
return 0;
}
void CAknDoubleSpanScrollBarExtension::DoScheduledDraw()
{
if(iParent)
iParent->DrawNow();
}
TInt CAknDoubleSpanScrollBarExtension::Reserved_1(){return 0;};
TInt CAknDoubleSpanScrollBarExtension::Reserved_2(){return 0;};
//
// TAknDoubleSpanScrollBarModel class
//
//
// This class stores its own model in its base class (TEikScrollBarModel)
// member variables as following:
//
//
// bits 31 to 0
//
// ZZAAAAAAAAAAAAA BBBBBBBBBBBBBBBB (iScrollSpane)
// CCCCCCCCCCCCCCC DDDDDDDDDDDDDDDD (iThumbSpan)
// EEEEEEEEEEEEEEE FFFFFFFFFFFFFFFF (iThumbPosition)
//
// Bits ZZ = model type.
// 00 EikScrollBarModel
// 11 EikScrollBarModel
// 10 TAknDoubleSpanScrollBarModel
// 01 Reserved for future
//
// Bits AAAAAAAAAAAAA = scale
// Bits BBBBBBBBBBBBBBB = scroll span
// Bits CCCCCCCCCCCCCCC = focus position
// Bits DDDDDDDDDDDDDDD = field position
// Bits EEEEEEEEEEEEEEE = field size
// Bits FFFFFFFFFFFFFFF = window size
//
//
// Reason for this solution is to preserve binary compatibility with the old model.
//
// If this model is not supported by the scrollbar system, then values are stored
// as in the base class for compatibility resons.
EXPORT_C TAknDoubleSpanScrollBarModel::TAknDoubleSpanScrollBarModel()
{
if (ModelIsSupported())
{
SetScrollBarModelType(EAknDoubleSpanScrollBarModel);
SetScale(KDoubleSpanMinScaleValue);
SetScrollSpanValue(0);
SetFocusPositionValue(0);
SetFieldPositionValue(0);
SetFieldSizeValue(0);
SetWindowSizeValue(0);
}
else
{
iScrollSpan = 0;
iThumbSpan = 0;
iThumbPosition = 0;
}
}
EXPORT_C TAknDoubleSpanScrollBarModel::TAknDoubleSpanScrollBarModel(const TEikScrollBarModel& aEikModel)
{
if(aEikModel.ScrollBarModelType() == EAknDoubleSpanScrollBarModel)
{
const TAknDoubleSpanScrollBarModel* model = static_cast <const TAknDoubleSpanScrollBarModel*> (&aEikModel);
// if parameter is
if (model->ModelIsSupported())
{
iScrollSpan = aEikModel.iScrollSpan;
iThumbSpan = aEikModel.iThumbSpan;
iThumbPosition = aEikModel.iThumbPosition;
}
else if(!ModelIsSupported() && model->ModelIsSupported())
{
SetScrollBarModelType(EAknDoubleSpanScrollBarModel);
SetScale(KDoubleSpanMinScaleValue);
SetScrollSpan(CheckMinMaxValue(model->ScrollSpan()));
SetFocusPosition(CheckMinMaxValue(model->FocusPosition()));
SetWindowSize(CheckMinMaxValue(model->WindowSize()));
SetFieldPositionValue(0);
SetFieldSizeValue(0);
}
}
// if parameter is only eikscb
else if(ModelIsSupported() && aEikModel.ScrollBarModelType() == EEikScrollBarModel)
{
SetScrollBarModelType(EAknDoubleSpanScrollBarModel);
SetScale(KDoubleSpanMinScaleValue);
SetScrollSpan(CheckMinMaxValue(aEikModel.iScrollSpan));
SetFocusPosition(CheckMinMaxValue(aEikModel.iThumbPosition));
SetWindowSize(CheckMinMaxValue(aEikModel.iThumbSpan));
SetFieldPositionValue(0);
SetFieldSizeValue(0);
}
else
{
SetScrollBarModelType(EAknDoubleSpanScrollBarModel);
SetScale(KDoubleSpanMinScaleValue);
SetScrollSpan(CheckMinMaxValue(aEikModel.iScrollSpan));
SetFocusPosition(CheckMinMaxValue(aEikModel.iThumbPosition));
SetWindowSize(CheckMinMaxValue(aEikModel.iThumbSpan));
SetFieldPositionValue(0);
SetFieldSizeValue(0);
}
}
EXPORT_C TInt TAknDoubleSpanScrollBarModel::ScrollSpan() const
{
if (ModelIsSupported())
{
// Assert that API user has not set TEikScrollBarModel values directly
__ASSERT_ALWAYS(ScrollBarModelType() == EAknDoubleSpanScrollBarModel,Panic(EEikPanicOutOfRange));
return Scale() * ScrollSpanValue();
}
else
{
return iScrollSpan;
}
}
EXPORT_C void TAknDoubleSpanScrollBarModel::SetScrollSpan(TInt aScrollSpan)
{
if (ModelIsSupported())
{
// Assert that API user has not set TEikScrollBarModel values directly
__ASSERT_ALWAYS(ScrollBarModelType() == EAknDoubleSpanScrollBarModel,Panic(EEikPanicOutOfRange));
SetScrollSpanValue(PrepareScaledValue(CheckMinMaxValue(aScrollSpan)));
}
else
{
iScrollSpan = aScrollSpan;
}
}
EXPORT_C TInt TAknDoubleSpanScrollBarModel::FocusPosition() const
{
if (ModelIsSupported())
{
// Assert that API user has not set TEikScrollBarModel values directly
__ASSERT_ALWAYS(ScrollBarModelType() == EAknDoubleSpanScrollBarModel,Panic(EEikPanicOutOfRange));
return Scale() * FocusPositionValue();
}
else
{
return iThumbPosition;
}
}
EXPORT_C void TAknDoubleSpanScrollBarModel::SetFocusPosition(TInt aFocusPosition)
{
if (ModelIsSupported())
{
// Assert that API user has not set TEikScrollBarModel values directly
__ASSERT_ALWAYS(ScrollBarModelType() == EAknDoubleSpanScrollBarModel,Panic(EEikPanicOutOfRange));
SetFocusPositionValue(PrepareScaledValue(CheckMinMaxValue(aFocusPosition)));
}
else
{
iThumbPosition = aFocusPosition;
}
}
EXPORT_C TInt TAknDoubleSpanScrollBarModel::FieldPosition() const
{
if (ModelIsSupported())
{
// Assert that API user has not set TEikScrollBarModel values directly
__ASSERT_ALWAYS(ScrollBarModelType() == EAknDoubleSpanScrollBarModel,Panic(EEikPanicOutOfRange));
return Scale() * FieldPositionValue();
}
else
{
return 0;
}
}
EXPORT_C void TAknDoubleSpanScrollBarModel::SetFieldPosition(TInt aFieldPosition)
{
if (ModelIsSupported())
{
// Assert that API user has not set TEikScrollBarModel values directly
__ASSERT_ALWAYS(ScrollBarModelType() == EAknDoubleSpanScrollBarModel,Panic(EEikPanicOutOfRange));
SetFieldPositionValue(PrepareScaledValue(CheckMinMaxValue(aFieldPosition)));
}
else
{
// do nothing
}
}
EXPORT_C TInt TAknDoubleSpanScrollBarModel::FieldSize() const
{
if (ModelIsSupported())
{
// Assert that API user has not set TEikScrollBarModel values directly
__ASSERT_ALWAYS(ScrollBarModelType() == EAknDoubleSpanScrollBarModel,Panic(EEikPanicOutOfRange));
return Scale() * FieldSizeValue();
}
else
{
return 0;
}
}
EXPORT_C void TAknDoubleSpanScrollBarModel::SetFieldSize(TInt aFieldSize)
{
if (ModelIsSupported())
{
// Assert that API user has not set TEikScrollBarModel values directly
__ASSERT_ALWAYS(ScrollBarModelType() == EAknDoubleSpanScrollBarModel,Panic(EEikPanicOutOfRange));
SetFieldSizeValue(PrepareScaledValue(CheckMinMaxValue(aFieldSize)));
}
else
{
// do nothing
}
}
EXPORT_C TInt TAknDoubleSpanScrollBarModel::WindowSize() const
{
if (ModelIsSupported())
{
// Assert that API user has not set TEikScrollBarModel values directly
__ASSERT_ALWAYS(ScrollBarModelType() == EAknDoubleSpanScrollBarModel,Panic(EEikPanicOutOfRange));
return Scale() * WindowSizeValue();
}
else
{
return iThumbSpan;
}
}
EXPORT_C void TAknDoubleSpanScrollBarModel::SetWindowSize (TInt aWindowSize)
{
if (ModelIsSupported())
{
// Assert that API user has not set TEikScrollBarModel values directly
__ASSERT_ALWAYS(ScrollBarModelType() == EAknDoubleSpanScrollBarModel,Panic(EEikPanicOutOfRange));
SetWindowSizeValue(PrepareScaledValue(CheckMinMaxValue(aWindowSize)));
}
else
{
iThumbSpan = aWindowSize;
}
}
TUint16 TAknDoubleSpanScrollBarModel::Scale() const
{
TUint16 scale = TUint16(KDoubleSpanModelMaskBitsScale16 & HighBytes(iScrollSpan));
return scale;
}
void TAknDoubleSpanScrollBarModel::SetScale(TUint16 aScale)
{
__ASSERT_ALWAYS(aScale != 0,Panic(EEikPanicOutOfRange));
__ASSERT_ALWAYS(aScale <= KDoubleSpanMaxScaleValue,Panic(EEikPanicOutOfRange));
iScrollSpan &= ~KDoubleSpanModelMaskBitsScale;
iScrollSpan |= KDoubleSpanModelMaskBitsScale & (TInt(aScale) << 16);
}
// getter/setters for raw values without scaling
TInt16 TAknDoubleSpanScrollBarModel::ScrollSpanValue() const
{
return LowBytes(iScrollSpan);
}
void TAknDoubleSpanScrollBarModel::SetScrollSpanValue(TInt16 aScrollSpan)
{
SetLowBytes(iScrollSpan, aScrollSpan);
}
TInt16 TAknDoubleSpanScrollBarModel::FocusPositionValue() const
{
return HighBytes(iThumbSpan);
}
void TAknDoubleSpanScrollBarModel::SetFocusPositionValue(TInt16 aFocusPosition)
{
SetHighBytes(iThumbSpan, aFocusPosition);
}
TInt16 TAknDoubleSpanScrollBarModel::FieldPositionValue() const
{
return LowBytes(iThumbSpan);
}
void TAknDoubleSpanScrollBarModel::SetFieldPositionValue(TInt16 aFieldPosition)
{
SetLowBytes(iThumbSpan, aFieldPosition);
}
TInt16 TAknDoubleSpanScrollBarModel::FieldSizeValue() const
{
return HighBytes(iThumbPosition);
}
void TAknDoubleSpanScrollBarModel::SetFieldSizeValue(TInt16 aFieldSize)
{
SetHighBytes(iThumbPosition, aFieldSize);
}
TInt16 TAknDoubleSpanScrollBarModel::WindowSizeValue() const
{
return LowBytes(iThumbPosition);
}
void TAknDoubleSpanScrollBarModel::SetWindowSizeValue(TInt16 aWindowSize)
{
SetLowBytes(iThumbPosition, aWindowSize);
}
TInt16 TAknDoubleSpanScrollBarModel::LowBytes(TInt aInt) const
{
return TInt16(KDoubleSpanModelMaskBitsLow & aInt);
}
TInt16 TAknDoubleSpanScrollBarModel::HighBytes(TInt aInt) const
{
return TInt16((KDoubleSpanModelMaskBitsHigh & aInt) >> 16);
}
void TAknDoubleSpanScrollBarModel::SetLowBytes(TInt& aInt, TInt16 aValue)
{
aInt &= KDoubleSpanModelMaskBitsHigh;
aInt |= TInt(KDoubleSpanModelMaskBitsLow & aValue);
}
void TAknDoubleSpanScrollBarModel::SetHighBytes(TInt& aInt, TInt16 aValue)
{
aInt &= KDoubleSpanModelMaskBitsLow;
aInt |= TInt(aValue) << 16;
}
TInt16 TAknDoubleSpanScrollBarModel::PrepareScaledValue(TInt aNonScaledValue)
{
__ASSERT_ALWAYS(KDoubleSpanMinModelValue <= aNonScaledValue && aNonScaledValue <= KDoubleSpanMaxModelValue, Panic(EEikPanicOutOfRange));
TUint16 requiredScale = KDoubleSpanMinScaleValue;
if (aNonScaledValue < 0)
{
requiredScale = TUint16(( -aNonScaledValue / KDoubleSpanMaxRawValue ) + KDoubleSpanMinScaleValue);
}
else
{
requiredScale = TUint16(( aNonScaledValue / KDoubleSpanMaxRawValue ) + KDoubleSpanMinScaleValue);
}
if ( requiredScale > Scale() )
{
ReScale( requiredScale );
}
TInt16 scaledValue = TInt16(aNonScaledValue / Scale());
return scaledValue;
}
void TAknDoubleSpanScrollBarModel::ReScale(TUint16 aNewScale)
{
__ASSERT_ALWAYS(aNewScale != 0,Panic(EEikPanicOutOfRange));
__ASSERT_ALWAYS(aNewScale <= KDoubleSpanMaxScaleValue,Panic(EEikPanicOutOfRange));
SetScrollSpanValue(TInt16((ScrollSpanValue() * Scale())/aNewScale));
SetFocusPositionValue(TInt16((FocusPositionValue() * Scale())/aNewScale));
SetFieldPositionValue(TInt16((FieldPositionValue() * Scale())/aNewScale));
SetFieldSizeValue(TInt16((FieldSizeValue() * Scale())/aNewScale));
SetWindowSizeValue(TInt16((WindowSizeValue() * Scale())/aNewScale));
SetScale(aNewScale);
}
void TAknDoubleSpanScrollBarModel::SetScrollBarModelType(TEikScrollBarModelType aModelType)
{
iScrollSpan &= KDoubleSpanModelMaskBitsType;
iScrollSpan |= (~KDoubleSpanModelMaskBitsType) & aModelType;
}
TInt TAknDoubleSpanScrollBarModel::CheckMinMaxValue(TInt aValue)
{
if ((aValue > 0) && (aValue > KDoubleSpanMaxModelValue))
{
return KDoubleSpanMaxModelValue;
}
if ((aValue < 0) && (aValue < KDoubleSpanMinModelValue))
{
return KDoubleSpanMinModelValue;
}
return aValue;
}
TBool TAknDoubleSpanScrollBarModel::ModelIsSupported()
{
// Check here feature flags etc. to decide if this device can support this
// type of model and scrollbars.
return ETrue;
}
TRect CAknDoubleSpanScrollBar::ExtensionArea() const
{
// Usage of hard-coded parent rectangle is acceptable since we're
// interested in only about the ratio between scrollbar and extension.
TAknLayoutRect layoutRect;
layoutRect.LayoutRect( TRect( 0, 0, 200, 200 ), AknLayoutScalable_Avkon::listscroll_gen_pane( 0 ).LayoutLine() );
TRect parent( layoutRect.Rect() ); // parent of both extension and scrollbar
layoutRect.LayoutRect( parent, AknLayoutScalable_Avkon::scroll_pane( 0 ).LayoutLine() );
TRect scrollbar( layoutRect.Rect() );
CAknDoubleSpanScrollBarExtension* extension1 = static_cast<CAknDoubleSpanScrollBarExtension*> (iExtension);
if( extension1->iExtensionType & ENormalExpandedTouchArea )
layoutRect.LayoutRect( parent, AknLayoutScalable_Avkon::aid_size_touch_scroll_bar( 0 ).LayoutLine() );
else if( extension1->iExtensionType & EScaleExpandedTouchArea )
layoutRect.LayoutRect( parent, AknLayoutScalable_Avkon::aid_size_touch_scroll_bar_cale( 0 ).LayoutLine() );
else
layoutRect.LayoutRect( parent, AknLayoutScalable_Avkon::aid_size_touch_scroll_bar( 0 ).LayoutLine() );
TRect extension( layoutRect.Rect() );
TRect area;
if ( iParentControl )
{
CCoeControl* windowOwningParent = iParentControl;
while ( windowOwningParent && !windowOwningParent->OwnsWindow() )
{
windowOwningParent = windowOwningParent->Parent();
}
if ( windowOwningParent )
{
TInt xGap = 0;
TRect scrollBarRect = Rect();
TRect parentRect = windowOwningParent->Rect();
if ( OwnsWindow() )
{
scrollBarRect.Move( Position().iX -
windowOwningParent->Position().iX, 0 );
}
if ( iOrientation == CEikScrollBar::EVertical )
{
// left to right layout in use
if ( !AknLayoutUtils::LayoutMirrored() )
{
xGap = parentRect.iBr.iX - scrollBarRect.iBr.iX;
if ( Abs( xGap ) < scrollBarRect.Width() )
{
extension.iBr.iX += xGap;
}
}
// right to left layout in use
else
{
xGap = parentRect.iTl.iX - scrollBarRect.iTl.iX;
if ( Abs( xGap ) < scrollBarRect.Width() )
{
extension.iTl.iX += xGap;
}
}
}
else
{
xGap = parentRect.iBr.iY - scrollBarRect.iBr.iY;
if ( Abs( xGap ) < scrollBarRect.Height() )
{
extension.iBr.iY += xGap;
}
}
}
}
if ( iOrientation == CEikScrollBar::EVertical )
{
area.iTl.iX = extension.iTl.iX - scrollbar.iTl.iX;
area.iTl.iY = scrollbar.iTl.iY - extension.iTl.iY;
area.iBr.iX = area.iTl.iX + extension.Width();
area.iBr.iY = iSize.iHeight + ( extension.Height() - scrollbar.Height() );
}
else
{
area.iTl.iX = scrollbar.iTl.iY - extension.iTl.iY;
area.iTl.iY = scrollbar.Width() - extension.Width();
area.iBr.iX = iSize.iWidth + ( extension.Height() - scrollbar.Height() );
area.iBr.iY = area.iTl.iY + extension.Width();
}
return area;
}