diff -r 000000000000 -r 2f259fa3e83a uifw/EikStd/coctlsrc/EIKSCRLB.CPP --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uifw/EikStd/coctlsrc/EIKSCRLB.CPP Tue Feb 02 01:00:49 2010 +0200 @@ -0,0 +1,2398 @@ +/* +* 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 +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "AknDoubleSpanScrollIndicator.h" +#include "eikscrlb.h" +#include "EIKSBEXT.H" + +const TInt KIntensity = 50; // 50% + +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 (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 (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 (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 (iExtension); + extension->SetScrollBarObserver(aScrollBarObserver); + } + else + { + CEikScrollBarExtension* extension = static_cast (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::CreateButtonL(CAknScrollButton*& /*aButton*/,CAknScrollButton::TType /*aType*/) + { + } + +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 (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); + if ( CAknEnv::Static()->TransparencyEnabled() ) + { + Window().SetRequiredDisplayMode( EColor16MA ); + if ( Window().SetTransparencyAlphaChannel() == KErrNone ) + { + Window().SetBackgroundColor( ~0 ); + } + } + } + else if(aParent) + { + SetContainerWindowL(*aParent); + } + else + { + User::Leave(KErrArgument); + } + + if( aParent ) + SetObserver(aParent->Observer()); + else + SetObserver(NULL); + + iOrientation=aOrientation; + CreateRequiredComponentsL(); + + if (aWindowOwning) + { + Window().SetPointerGrab(ETrue); + EnableDragEvents(); + if (extension->iScrollIndicator) + extension->iScrollIndicator->SetAsWindowOwning(ETrue); + + + // By default set background to transparent + SetTransparentBackground(ETrue); + } + + 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 (iExtension); + if ( aVisible && (extension->iScrollIndicator->ScrollSpan() > 0) ) + { + 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 (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 (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 ( modifier && IsVisible() ) + { + modifier->Update( *this, ExtensionArea() ); + } + + AknsUtils::RegisterControlPosition( this ); + if (iExtension) + { + CAknDoubleSpanScrollBarExtension* extension = static_cast (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 (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 ); + } + } + + // 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; + } + } + + 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; + } + } + + // 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) + { + // Smooth continuous tactile feedback is produced + // during thumb dragging. The tactile feedback API + // filters out possible re-startings of the effect. + MTouchFeedback* feedback = MTouchFeedback::Instance(); + + if ( feedback ) + { + TTimeIntervalMicroSeconds32 timeout( 300000 ); + feedback->StartFeedback( this, + ETouchContinuousSlider, + &aPointerEvent, + KIntensity, // intensity 50% + timeout ); + } + 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: + { + // Stop the continuous tactile feedback that may be playing + // at the time due to possible previous thumb dragging. + MTouchFeedback* feedback = MTouchFeedback::Instance(); + + if ( feedback ) + { + feedback->StopFeedback( this ); + } + } + + 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 (iExtension); + extension->iFixedLayoutRect = aScrollBarRect; + SetRect(aScrollBarRect); + } + } + +EXPORT_C void CAknDoubleSpanScrollBar::SetScrollPopupInfoTextL( const TDesC& aText ) + { + if ( !AknLayoutUtils::PenEnabled() ) + { + return; + } + + if ( iExtension ) + { + CAknDoubleSpanScrollBarExtension* extension = static_cast (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 (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 (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 (iExtension); + CAknDoubleSpanScrollIndicator* indicator = extension->iScrollIndicator; + + return indicator->DrawBackgroundState(); + } + +void CAknDoubleSpanScrollBar::DrawBackground(TBool aDraw) + { + CAknDoubleSpanScrollBarExtension* extension = static_cast (iExtension); + CAknDoubleSpanScrollIndicator* indicator = extension->iScrollIndicator; + + indicator->SetDrawBackgroundState(aDraw); + } + + +// --------------------------------------------------------------------------- +// CAknDoubleSpanScrollBar::ResetPressedDownHighlight +// --------------------------------------------------------------------------- +// +void CAknDoubleSpanScrollBar::ResetPressedDownHighlight() + { + CAknDoubleSpanScrollBarExtension* extension = + static_cast( 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 (&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 (&iParent->iModel)->FocusPosition(); + } + else + { + TAknDoubleSpanScrollBarModel& model = static_cast (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::CreateButtonL(CAknScrollButton*& /*aButton*/,CAknScrollButton::TType /*aType*/) + { + } + +void CAknDoubleSpanScrollBarExtension::DoSetModel(const TEikScrollBarModel* aModel) + { + iParent->iModel=(*aModel); + if (iScrollIndicator) + { + if (aModel->ScrollBarModelType() == TEikScrollBarModel::EAknDoubleSpanScrollBarModel) + { + const TAknDoubleSpanScrollBarModel* model = static_cast (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 (iParent->OwnsWindow() && iScrollIndicator->TransparentBackground()) + { + iParent->Window().HandleTransparencyUpdate(); + } + 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 (&iPreviousModel); + const TAknDoubleSpanScrollBarModel* model = static_cast (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 (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 (&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); + } + + 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( 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 (&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 (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 ( 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; + } +