diff -r 000000000000 -r 2f259fa3e83a uifw/EikStd/coctlsrc/EIKSBFRM.CPP --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uifw/EikStd/coctlsrc/EIKSBFRM.CPP Tue Feb 02 01:00:49 2010 +0200 @@ -0,0 +1,1451 @@ +/* +* Copyright (c) 1997-1999 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "EIKSBEXT.H" + +// const TInt KCbaScrollBarWidth=9; + +// +// TEikScrollBarFrameLayout +// + +EXPORT_C TEikScrollBarFrameLayout::TEikScrollBarFrameLayout() + // + // default constructor + // + { + iInclusiveMargin.iTop = 0; + iInclusiveMargin.iBottom = 0; + iInclusiveMargin.iLeft = 0; + iInclusiveMargin.iRight = 0; + + iClientMargin.iTop = 0; + iClientMargin.iBottom = 0; + iClientMargin.iLeft = 0; + iClientMargin.iRight = 0; + + iClientAreaGranularity = TSize(0,0); + + iTilingMode = EClientRectConstant; + } + +EXPORT_C void TEikScrollBarFrameLayout::SetInclusiveMargin(TInt aMargin) + // + // sets all inclusive margins to aMargin + // + { + iInclusiveMargin.iTop = aMargin; + iInclusiveMargin.iBottom = aMargin; + iInclusiveMargin.iLeft = aMargin; + iInclusiveMargin.iRight = aMargin; + } + +EXPORT_C void TEikScrollBarFrameLayout::SetClientMargin(TInt aMargin) + // + // sets all client margins to aMargin + // + { + iClientMargin.iTop = aMargin; + iClientMargin.iBottom = aMargin; + iClientMargin.iLeft = aMargin; + iClientMargin.iRight = aMargin; + } + + +CEikScrollBarFrameExtension::CEikScrollBarFrameExtension() + { + + } + +CEikScrollBarFrameExtension::~CEikScrollBarFrameExtension() + { + + } + +// +// CEikScrollBarFrame +// + +enum TEikScrollBarFramePanic + { + ENoScrollBarFrame =0x01, + EFailedToRemoveExternalScrollBar, + EUnexpectedExternalScrollBarDisconnectRequest + }; + +GLDEF_C void SbfPanic(TEikScrollBarFramePanic aPanic) + { + _LIT(KPanicCategory, "UIKON - Scrollbar Frame"); + User::Panic(KPanicCategory, aPanic); + } + +// const TInt KTypeOfScrollBarMask=0x0300; +// const TInt KSideOfScrollBarMask=0x0c00; + + +enum // private flags + { + EDisplayHScrollBar =0x01, + EDisplayVScrollBar =0x02, + EDoNotAdjustHorizontalModel =0x04, + EDoNotAdjustVerticalModel =0x08, + EPreAllocScrollBars =0x10 + }; + +EXPORT_C CEikScrollBarFrame::~CEikScrollBarFrame() + { + DeleteScrollBars(); + delete iExtension; + } + +EXPORT_C CEikScrollBarFrame::CEikScrollBarFrame(CCoeControl* aParentWindow, MEikScrollBarObserver* aObserver, TBool /*aPreAlloc*/) + { + InitExtension(aParentWindow,aObserver); + GetScrollBars(EFalse); + } + +CEikScrollBarFrame::CEikScrollBarFrame(CCoeControl* aParentWindow, MEikScrollBarObserver* aObserver, TBool /*aPreAlloc*/, TBool aDoubleSpan) + { + InitExtension(aParentWindow,aObserver); + GetScrollBars(aDoubleSpan); + } + +void CEikScrollBarFrame::InitExtension(CCoeControl* aParentWindow, MEikScrollBarObserver* aObserver) + { + iExtension = new CEikScrollBarFrameExtension(); + if (iExtension) + { + iExtension->iParentWindow = aParentWindow; + iExtension->iH.iModel = TAknDoubleSpanScrollBarModel(); + iExtension->iH.iBar = NULL; + iExtension->iH.iExternalScrollBarAttached = EFalse; + iExtension->iH.iVisibility = EOff; + if(AknLayoutUtils::PenEnabled()) + { + iExtension->iScrollBarObserver = aObserver; + } + } + } + +void CEikScrollBarFrame::DisconnectExternalScrollBar(CEikScrollBar* aScrollBar) + { + if (iV.iExternalScrollBarAttached && iV.iBar == aScrollBar) + { + iV.iExternalScrollBarAttached = EFalse; + iV.iBar = NULL; + } + + if (iExtension && iExtension->iH.iExternalScrollBarAttached && iExtension->iH.iBar == aScrollBar) + { + iExtension->iH.iExternalScrollBarAttached = EFalse; + iExtension->iH.iBar = NULL; + } + } + +void CEikScrollBarFrame::GetScrollBars(TBool aDoubleSpan) + { + if (!iV.iBar) + { + CEikCba* cba=GetCurrentCba(); + if (cba) + { + // If aDoubleSpan is true, we will optimize and do not create arrow heads at all. + // There will come CreateDoubleSpanScrollBarsL call, and arrow heads are not needed. + if ( !(aDoubleSpan && (AknLayoutUtils::DefaultScrollBarType(iAvkonAppUi) == CEikScrollBarFrame::EDoubleSpan)) ) + { + TRAP_IGNORE(cba->CreateArrowHeadScrollBarL()); + } + // returns the vertical scroll bar from the top scroll bar host + iV.iBar=cba->VScrollBarAsControl(); + iV.iExternalScrollBarAttached=ETrue; + TRAPD(err, iV.iBar->AddExternalFrameL(this)); + if (err) + { + iV.iExternalScrollBarAttached = EFalse; + iV.iBar = NULL; + } + } + } + } + +EXPORT_C void CEikScrollBarFrame::DrawScrollBarsNow() const +// Force a redraw of any scrollbars + { + if (iV.iBar && iExtension && iExtension->iParentWindow->IsVisible()) + iV.iBar->DrawNow(); + + if (iExtension && iExtension->iH.iBar && iExtension->iParentWindow->IsVisible()) + iExtension->iH.iBar->DrawNow(); + + } + +void CEikScrollBarFrame::DrawScrollBarsDeferred() const + { + if (iV.iBar && iExtension && iExtension->iParentWindow->IsVisible()) + { + iV.iBar->DrawDeferred(); + } + + if (iExtension && iExtension->iH.iBar && iExtension->iParentWindow->IsVisible()) + { + iExtension->iH.iBar->DrawDeferred(); + } + } + +const TInt KLongEnoughToCauseComponentsToBeCreated=200; + + +EXPORT_C void CEikScrollBarFrame::SetScrollBarVisibilityL(TScrollBarVisibility aHVisibility, TScrollBarVisibility aVVisibility) +// Set the visibility state for both scrollbars to be used when tiling + { + __ASSERT_DEBUG(this, SbfPanic(ENoScrollBarFrame)); + + // Vertical scrollbar + iV.iVisibility=aVVisibility; + if (iV.iBar && TypeOfVScrollBar() == EDoubleSpan && aVVisibility==EOff) + { + iScrollBarFrameFlags&=(~EDisplayVScrollBar); + MakeSBarVisible(iV, EFalse); + } + + // Horizontal scrollbar + if (iExtension) + { + iExtension->iH.iVisibility=aHVisibility; + if (iExtension->iH.iBar && TypeOfHScrollBar() == EDoubleSpan && aHVisibility==EOff) + { + iScrollBarFrameFlags&=(~EDisplayHScrollBar); + MakeSBarVisible(iExtension->iH, EFalse); + } + } + } + +EXPORT_C TBool CEikScrollBarFrame::Tile(TEikScrollBarModel* aVModel) + // + // The main function which provides the necessary scrollbars according to visibilities and size considerations + // returns ETrue if the "output rect" was changed + // + { + GetScrollBars(EFalse); + CalcTheoreticalScrollBarVisibility(aVModel); + if (iV.iVisibility!=EOff) + iV.iModel = *aVModel; + MakeSBarVisible(iV, iScrollBarFrameFlags&EDisplayVScrollBar); + return EFalse; + } + +EXPORT_C TBool CEikScrollBarFrame::TileL(TEikScrollBarModel* aHModel, TEikScrollBarModel* aVModel, + TRect& aClientRect, TRect& aInclusiveRect, const TEikScrollBarFrameLayout& aLayout) + { + TRect tempRect(aClientRect); + if(aClientRect.Height() < 0 ) + { + aClientRect.iTl.iY = aClientRect.iBr.iY; + aClientRect.iBr.iY = tempRect.iTl.iY; + } + if(aClientRect.Width() < 0 ) + { + aClientRect.iTl.iX = aClientRect.iBr.iX; + aClientRect.iBr.iX = tempRect.iTl.iX; + } + tempRect = aInclusiveRect; + if(aInclusiveRect.Height() < 0 ) + { + aInclusiveRect.iTl.iY = aInclusiveRect.iBr.iY; + aInclusiveRect.iBr.iY = tempRect.iTl.iY; + } + if(aInclusiveRect.Width() < 0 ) + { + aInclusiveRect.iTl.iX = aInclusiveRect.iBr.iX; + aInclusiveRect.iBr.iX = tempRect.iTl.iX; + } + if (iExtension && iExtension->iH.iVisibility!=EOff) + { + if(aClientRect.Height() < ScrollBarBreadth( CEikScrollBar::EHorizontal) ) + { + aClientRect.SetHeight( ScrollBarBreadth(CEikScrollBar::EHorizontal) ); + } + if(aInclusiveRect.Height() < ScrollBarBreadth( CEikScrollBar::EHorizontal) ) + { + aInclusiveRect.SetHeight( ScrollBarBreadth(CEikScrollBar::EHorizontal) ); + } + } + TBool sizeChanged = EFalse; + + GetScrollBars(EFalse); + CalcTheoreticalScrollBarVisibility(aVModel,aHModel); + + if (iV.iVisibility!=EOff) + iV.iModel = *aVModel; + + MakeSBarVisible(iV, iScrollBarFrameFlags&EDisplayVScrollBar); + + if (iExtension && iExtension->iH.iBar) + { + if (iExtension->iH.iVisibility!=EOff) + iExtension->iH.iModel = *aHModel; + + MakeSBarVisible(iExtension->iH, iScrollBarFrameFlags&EDisplayHScrollBar); + } + + // Vertical Double span scollbar + if (iV.iBar && TypeOfVScrollBar() == EDoubleSpan && iV.iExternalScrollBarAttached==EFalse ) + { + TInt scrollBarWidth = ScrollBarBreadth(CEikScrollBar::EVertical); // is 0 if SB not visible ! + TInt horizontalScrollBarWidth = 0; + if (iExtension && iExtension->iH.iVisibility!=EOff) + { + horizontalScrollBarWidth = ScrollBarBreadth(CEikScrollBar::EHorizontal); + } + CAknDoubleSpanScrollBar* scrollbar = static_cast (iV.iBar); + if (scrollbar->FixedLayoutRect().Size() == TSize(0,0)) + { + TMargins checkedClientMargin(aLayout.iClientMargin); + TMargins checkedInclusiveMargin(aLayout.iInclusiveMargin); + checkedClientMargin.iTop = Max(0,checkedClientMargin.iTop); + checkedClientMargin.iBottom = Max(0,checkedClientMargin.iBottom); + checkedClientMargin.iRight = Max(0,checkedClientMargin.iRight); + checkedClientMargin.iLeft = Max(0,checkedClientMargin.iLeft); + + checkedInclusiveMargin.iTop = Max(0,checkedInclusiveMargin.iTop); + checkedInclusiveMargin.iBottom = Max(0,checkedInclusiveMargin.iBottom); + checkedInclusiveMargin.iRight = Max(0,checkedInclusiveMargin.iRight); + checkedInclusiveMargin.iLeft = Max(0,checkedInclusiveMargin.iLeft); + + TInt width = 0; + TInt xPos = 0; + TInt yPos = 0; + TInt height = 0; + + if (!AknLayoutUtils::LayoutMirrored()) + { + if (aLayout.iTilingMode == TEikScrollBarFrameLayout::EInclusiveRectConstant) + { + width = scrollBarWidth + checkedInclusiveMargin.iRight; + xPos = aInclusiveRect.iBr.iX - width; + yPos = aInclusiveRect.iTl.iY + checkedInclusiveMargin.iTop; + height = aInclusiveRect.Size().iHeight - (checkedInclusiveMargin.iTop + checkedInclusiveMargin.iBottom) - horizontalScrollBarWidth; + + if ((aClientRect.iBr.iX + width > aInclusiveRect.iBr.iX) || (aInclusiveRect.iBr.iX - width > aClientRect.iBr.iX)) + { + aClientRect.iBr.iX = aInclusiveRect.iBr.iX - width; + sizeChanged = ETrue; + } + } + else + { + width = scrollBarWidth + checkedClientMargin.iRight; + xPos = aClientRect.iBr.iX + checkedClientMargin.iRight; + yPos = aInclusiveRect.iTl.iY + checkedInclusiveMargin.iTop; + height = aInclusiveRect.Size().iHeight - (checkedInclusiveMargin.iTop + checkedInclusiveMargin.iBottom) - horizontalScrollBarWidth; + + if ((aClientRect.iBr.iX + width + checkedInclusiveMargin.iRight > aInclusiveRect.iBr.iX) || + (aInclusiveRect.iBr.iX - (width + checkedInclusiveMargin.iRight) > aClientRect.iBr.iX)) + { + aInclusiveRect.iBr.iX = aClientRect.iBr.iX + width + checkedInclusiveMargin.iRight; + sizeChanged = ETrue; + } + } + } + else + { + // Mirrored Left & Right + if (aLayout.iTilingMode == TEikScrollBarFrameLayout::EInclusiveRectConstant) + { + width = scrollBarWidth + checkedInclusiveMargin.iRight; + xPos = aInclusiveRect.iTl.iX + checkedInclusiveMargin.iRight; + yPos = aInclusiveRect.iTl.iY + checkedInclusiveMargin.iTop; + height = aInclusiveRect.Size().iHeight - (checkedInclusiveMargin.iTop + checkedInclusiveMargin.iBottom) - horizontalScrollBarWidth; + + if ((aClientRect.iTl.iX - width < aInclusiveRect.iTl.iX) || (aInclusiveRect.iTl.iX + width > aClientRect.iTl.iX)) + { + aClientRect.iTl.iX = aInclusiveRect.iTl.iX + width; + xPos = aInclusiveRect.iTl.iX + checkedInclusiveMargin.iRight; + sizeChanged = ETrue; + } + } + else + { + width = scrollBarWidth + checkedClientMargin.iRight; + xPos = aClientRect.iTl.iX - checkedClientMargin.iRight; + yPos = aInclusiveRect.iTl.iY + checkedInclusiveMargin.iTop; + height = aInclusiveRect.Size().iHeight - (checkedInclusiveMargin.iTop + checkedInclusiveMargin.iBottom) - horizontalScrollBarWidth; + + if ((aClientRect.iTl.iX - width - checkedInclusiveMargin.iRight > aInclusiveRect.iTl.iX) || + (aInclusiveRect.iTl.iX - (width + checkedInclusiveMargin.iRight) < aClientRect.iTl.iX)) + { + aInclusiveRect.iTl.iX = aClientRect.iTl.iX - width - checkedInclusiveMargin.iRight; + xPos = aInclusiveRect.iTl.iX + checkedInclusiveMargin.iRight; + sizeChanged = ETrue; + } + } + + } + + TRect newRect = TRect(TPoint(xPos, yPos), TSize(width, height )); + if (iV.iBar->IsVisible() && (newRect != TRect(iV.iBar->Position(), iV.iBar->Size()))) + { + iV.iBar->SetRect(newRect); + } + + } + } + + // Horizontal Double span scollbar + if (iExtension && + iExtension->iH.iBar && + TypeOfHScrollBar() == EDoubleSpan && + iExtension->iH.iExternalScrollBarAttached==EFalse ) + { + TInt scrollBarWidth = ScrollBarBreadth(CEikScrollBar::EHorizontal); // is 0 if SB not visible ! + TInt verticalScrollBarWidth = 0; + if (iV.iVisibility!=EOff) + { + verticalScrollBarWidth = ScrollBarBreadth(CEikScrollBar::EVertical); + } + CAknDoubleSpanScrollBar* scrollbar = static_cast (iExtension->iH.iBar); + if (scrollbar->FixedLayoutRect().Size() == TSize(0,0)) + { + TMargins checkedClientMargin(aLayout.iClientMargin); + TMargins checkedInclusiveMargin(aLayout.iInclusiveMargin); + checkedClientMargin.iTop = Max(0,checkedClientMargin.iTop); + checkedClientMargin.iBottom = Max(0,checkedClientMargin.iBottom); + checkedClientMargin.iRight = Max(0,checkedClientMargin.iRight); + checkedClientMargin.iLeft = Max(0,checkedClientMargin.iLeft); + + checkedInclusiveMargin.iTop = Max(0,checkedInclusiveMargin.iTop); + checkedInclusiveMargin.iBottom = Max(0,checkedInclusiveMargin.iBottom); + checkedInclusiveMargin.iRight = Max(0,checkedInclusiveMargin.iRight); + checkedInclusiveMargin.iLeft = Max(0,checkedInclusiveMargin.iLeft); + + TInt width = 0; + TInt xPos = 0; + TInt yPos = 0; + TInt height = 0; + + if (aLayout.iTilingMode == TEikScrollBarFrameLayout::EInclusiveRectConstant) + { + width = scrollBarWidth + checkedInclusiveMargin.iBottom; // width as vertical direction (height). + xPos = aInclusiveRect.iTl.iX + checkedInclusiveMargin.iLeft; + if (AknLayoutUtils::LayoutMirrored()) + { + xPos += verticalScrollBarWidth; + } + yPos = aInclusiveRect.iBr.iY - checkedInclusiveMargin.iBottom - width; + height = aInclusiveRect.Size().iWidth - (checkedInclusiveMargin.iLeft + checkedInclusiveMargin.iRight) - verticalScrollBarWidth; // height as horizontal (width). + + if ((aClientRect.iBr.iY + width > aInclusiveRect.iBr.iY) || (aInclusiveRect.iBr.iY - width > aClientRect.iBr.iY)) + { + aClientRect.iBr.iY = aInclusiveRect.iBr.iY - width; + sizeChanged = ETrue; + } + } + else + { + width = scrollBarWidth + checkedClientMargin.iBottom; // width as vertical direction (height). + xPos = aInclusiveRect.iTl.iX + checkedInclusiveMargin.iLeft; + if (AknLayoutUtils::LayoutMirrored()) + { + xPos += verticalScrollBarWidth; + } + yPos = aClientRect.iBr.iY + checkedClientMargin.iBottom; + height = aInclusiveRect.Size().iWidth - (checkedInclusiveMargin.iLeft + checkedInclusiveMargin.iRight) - verticalScrollBarWidth; // height as horizontal (width). + + if ((aClientRect.iBr.iY + width + checkedClientMargin.iBottom > aInclusiveRect.iBr.iY) || + (aInclusiveRect.iBr.iY - (width + checkedInclusiveMargin.iBottom) > aClientRect.iBr.iY)) + { + aInclusiveRect.iBr.iY = aClientRect.iBr.iY + width + checkedInclusiveMargin.iBottom; + sizeChanged = ETrue; + } + } + + TRect newRect = TRect(TPoint(xPos, yPos), TSize(height, width )); // height & width swapped + if (iExtension->iH.iBar->IsVisible() && (newRect != TRect(iV.iBar->Position(), iV.iBar->Size()))) + { + iExtension->iH.iBar->SetRect(newRect); + } + } + + } + + return sizeChanged; + } + +EXPORT_C void CEikScrollBarFrame::MoveThumbsBy(TInt aDeltaX, TInt aDeltaY) + // + // Used to update any scrollbar(s) after an external scroll + // values in terms of the model, presumed not to have changed spans. + // + { + // Vertical scrollbar + if (aDeltaY && iV.iBar) + { + if (TypeOfVScrollBar() == TScrollBarType(EArrowHead)) + { + iV.iModel.iThumbPosition += aDeltaY; + } + else + { + // EDoubleSpan has different model. + if (iV.iModel.ScrollBarModelType() == TEikScrollBarModel::EAknDoubleSpanScrollBarModel) + { + TAknDoubleSpanScrollBarModel* model = static_cast (&iV.iModel); + // Note that for a large scroll span and small delta this may not actually change focusposition + // because of the 15 bit accuracy of TAknDoubleSpanScrollBarModel values. + model->SetFocusPosition(model->FocusPosition() + aDeltaY); + } + 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("CEikScrollBarFrame: Please, use TAknDoubleSpanScrollBarModel instead of TEikScrollBarModel")); + // #endif + // In most cases we can work with the TEikScrollBarModel model. + iV.iModel.iThumbPosition += aDeltaY; + } + } + ApplyModel(iV); + } + + + // Horizontal scrollbar + if (aDeltaX && iExtension && iExtension->iH.iBar && TypeOfHScrollBar() == TScrollBarType(EDoubleSpan)) + { + if (iExtension->iH.iModel.ScrollBarModelType() == TEikScrollBarModel::EAknDoubleSpanScrollBarModel) + { + TAknDoubleSpanScrollBarModel* model = static_cast (&(iExtension->iH.iModel)); + // Note that for a large scroll span and small delta this may not actually change focusposition + // because of the 15 bit accuracy of TAknDoubleSpanScrollBarModel values. + model->SetFocusPosition(model->FocusPosition() + aDeltaX); + } + 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("CEikScrollBarFrame: Please, use TAknDoubleSpanScrollBarModel instead of TEikScrollBarModel")); + // #endif + // In most cases we can work with the TEikScrollBarModel model. + iExtension->iH.iModel.iThumbPosition += aDeltaX; + } + ApplyModel(iExtension->iH); + } + + } + +EXPORT_C void CEikScrollBarFrame::MoveVertThumbTo(TInt aVertThumbPos) + { + if (iV.iBar) + { + if (TypeOfVScrollBar() == TScrollBarType(EArrowHead)) + { + iV.iModel.iThumbPosition = aVertThumbPos; + } + else + { + // EDoubleSpan has different model. + if (iV.iModel.ScrollBarModelType() == TEikScrollBarModel::EAknDoubleSpanScrollBarModel) + { + TAknDoubleSpanScrollBarModel* model = static_cast (&iV.iModel); + model->SetFocusPosition(aVertThumbPos); + } + 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("CEikScrollBarFrame: Please, use TAknDoubleSpanScrollBarModel instead of TEikScrollBarModel")); + // #endif + // In most cases we can work with the TEikScrollBarModel model. + iV.iModel.iThumbPosition = aVertThumbPos; + } + } + ApplyModel(iV); + } + } + +EXPORT_C void CEikScrollBarFrame::SetVFocusPosToThumbPos(TInt aFocusPosition) + { + MoveVertThumbTo(aFocusPosition); + } + +EXPORT_C TInt CEikScrollBarFrame::ScrollBarBreadth(CEikScrollBar::TOrientation aOrientation) const + // + // return the appropriate scrollbar's breadth or zero if none exists + // + { + CAknScrollBar* sBar=(CAknScrollBar*)GetScrollBarHandle(aOrientation); + if (!sBar) + return 0; + return sBar->ScrollBarBreadth(); + } + +EXPORT_C TBool CEikScrollBarFrame::ScrollBarExists(CEikScrollBar::TOrientation aOrientation) const + // + // returns ETrue if the specified scrollbar exists + // + { + if (GetScrollBarHandle(aOrientation)) + return ETrue; + return EFalse; + } + +EXPORT_C TInt CEikScrollBarFrame::CountComponentControls() const + { + TInt numberOfComponents = 0; + + if (iV.iBar) + numberOfComponents++; + + if (iExtension && iExtension->iH.iBar) + numberOfComponents++; + + return numberOfComponents; + } + +EXPORT_C CCoeControl* CEikScrollBarFrame::ComponentControl(TInt aIndex) const + { + if (aIndex == 0) + { + if (iV.iBar) + return iV.iBar; + else + { + if (iExtension && iExtension->iH.iBar) + return iExtension->iH.iBar; + } + } + + if (aIndex == 1) + { + if (iExtension && iExtension->iH.iBar) + return iExtension->iH.iBar; + else + { + if (iV.iBar) + return iV.iBar; + } + } + + return NULL; + } + +EXPORT_C CEikScrollBar* CEikScrollBarFrame::GetScrollBarHandle(CEikScrollBar::TOrientation aOrientation) const + // + // returns the pointer to the appropriate scrollbar + // + { + if (aOrientation==CEikScrollBar::EVertical) + { + if (iScrollBarFrameFlags&EDisplayVScrollBar) + return(iV.iBar); + } + + if (aOrientation==CEikScrollBar::EHorizontal) + { + if (iScrollBarFrameFlags&EDisplayHScrollBar && iExtension) + return(iExtension->iH.iBar); + } + + return(NULL); + } + +EXPORT_C CEikScrollBar* CEikScrollBarFrame::VerticalScrollBar() const + // + // returns the vertical scroll bar + // + { + return iV.iBar; + } + +void CEikScrollBarFrame::CalcTheoreticalScrollBarVisibility(const TEikScrollBarModel* aVModel) + // + // Determines which scrollbars are necessary before size considerations are taken into account + // + { + // assume no scrollbars to start with + iScrollBarFrameFlags&=(~EDisplayVScrollBar); + + TBool scrollBarUseful = EFalse; + + switch(TypeOfVScrollBar()) + { + case EDoubleSpan: + { + if (aVModel->ScrollBarModelType() == TEikScrollBarModel::EAknDoubleSpanScrollBarModel) + { + //const TAknDoubleSpanScrollBarModel* model = static_cast (aVModel); + //scrollBarUseful = (model->FocusPosition() < model->ScrollSpan()) && (model->WindowSize() < model->ScrollSpan()); + scrollBarUseful = ETrue; // S60 style says double span scrollbar is always shown if visibility is EAuto + } + 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("CEikScrollBarFrame: Please, use TAknDoubleSpanScrollBarModel instead of TEikScrollBarModel")); + //#endif + // In most cases we can work with the TEikScrollBarModel model. + //scrollBarUseful = (aVModel->iThumbPosition < aVModel->iScrollSpan) && (aVModel->iThumbSpan < aVModel->iScrollSpan); + scrollBarUseful = ETrue; // S60 style says double span scrollbar is always shown if visibility is EAuto + } + break; + } + + case EArrowHead: // fallthrough + default: + { + scrollBarUseful = aVModel->ScrollBarUseful(); + break; + } + } + + if ( (iV.iVisibility==EOn) || ( (iV.iVisibility==EAuto)&&(scrollBarUseful) ) ) + { + iScrollBarFrameFlags|=EDisplayVScrollBar; + } + + } + +CEikCba* CEikScrollBarFrame::GetCurrentCba() + { + CEikCba* mopCba = NULL; + if (iExtension && iExtension->iParentWindow) + mopCba=iExtension->iParentWindow->MopGetObject(mopCba); + return mopCba; + } + +void CEikScrollBarFrame::ApplyModel(SBarData& aSBar) + { + if (iExtension && iExtension->iParentWindow && iExtension->iParentWindow->IsVisible() + && aSBar.iBar && aSBar.iBar->IsVisible()) + { + aSBar.iBar->SetModel(&aSBar.iModel); + } + } + +void CEikScrollBarFrame::MakeSBarVisible(SBarData& aSBar, TBool aVisible) + { + if (iExtension && iExtension->iParentWindow->IsVisible() && aSBar.iBar) + { + if (aVisible && iExtension->iParentWindow->IsVisible()) + { + aSBar.iBar->SetModel(&aSBar.iModel); + aSBar.iBar->MakeVisible(ETrue); + } + else if(!aVisible) + { + aSBar.iBar->MakeVisible(EFalse); + } + } + else if (TypeOfVScrollBar() == TScrollBarType(EDoubleSpan) && aSBar.iBar) + aSBar.iBar->SetModel(&aSBar.iModel); + } + +void CEikScrollBarFrame::SetParentWindow(CCoeControl* aParentWindow) + { + if (iExtension) + { + iExtension->iParentWindow=aParentWindow; + } + else + { + iExtension = new CEikScrollBarFrameExtension(); + if (iExtension) + { + iExtension->iParentWindow = aParentWindow; + iExtension->iH.iModel = TAknDoubleSpanScrollBarModel(); + iExtension->iH.iBar = NULL; + iExtension->iH.iExternalScrollBarAttached = EFalse; + iExtension->iH.iVisibility = EOff; + } + } + } + +CCoeControl* CEikScrollBarFrame::ParentWindow() const + { + if (iExtension) + { + return iExtension->iParentWindow; + } + else + { + return NULL; + } + } + + + +EXPORT_C void CEikScrollBarFrame::SetScrollBarFrameObserver(MEikScrollBarObserver* aObserver) + { + if( !AknLayoutUtils::PenEnabled() ) + { + return; + } + + iExtension->iScrollBarObserver = aObserver; + + if(iV.iBar) + { + iV.iBar->SetScrollBarObserver(aObserver); + } + if(iExtension && iExtension->iH.iBar) + { + iExtension->iH.iBar->SetScrollBarObserver(aObserver); + } + } + +MEikScrollBarObserver* CEikScrollBarFrame::ScrollBarFrameObserver() + { + if(AknLayoutUtils::PenEnabled()) + return iExtension->iScrollBarObserver; + else + return NULL; + } + +// Functions which don't do anything useful in the avkon UI +EXPORT_C void CEikScrollBarFrame::SetAdjustsHorizontalModel(TBool /*aAdjusts*/) + { + } + +EXPORT_C void CEikScrollBarFrame::SetAdjustsVerticalModel(TBool /*aAdjusts*/) + { + } + +EXPORT_C void CEikScrollBarFrame::MoveHorizThumbTo(TInt aHorizThumbPos) + { + if (iExtension && iExtension->iH.iBar) + { + if (TypeOfVScrollBar() == TScrollBarType(EDoubleSpan)) + { + // EDoubleSpan has different model. + if (iV.iModel.ScrollBarModelType() == TEikScrollBarModel::EAknDoubleSpanScrollBarModel) + { + TAknDoubleSpanScrollBarModel* model = static_cast (&(iExtension->iH.iModel)); + model->SetFocusPosition(aHorizThumbPos); + } + 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("CEikScrollBarFrame: Please, use TAknDoubleSpanScrollBarModel instead of TEikScrollBarModel")); + // #endif + // In most cases we can work with the TEikScrollBarModel model. + iExtension->iH.iModel.iThumbPosition = aHorizThumbPos; + } + } + ApplyModel(iExtension->iH); + } + } + +EXPORT_C void CEikScrollBarFrame::SetTypeOfHScrollBar(TScrollBarType aType) + { + if (iExtension && iExtension->iH.iBar) + { + if (TypeOfHScrollBar() == aType) + return; // already set to requested type + + if (aType == CEikScrollBarFrame::TScrollBarType(EDoubleSpan)) + { + TRAP_IGNORE(CreateDoubleSpanScrollBarsL(ETrue,EFalse)); // by default a window owning + return; + } + + if (aType == CEikScrollBarFrame::TScrollBarType(EArrowHead)) + { + return; // not supported + } + } + } + +EXPORT_C void CEikScrollBarFrame::SetTypeOfVScrollBar(TScrollBarType aType) + { + if (iV.iBar) + { + if (TypeOfVScrollBar() == aType) + return; // already set to requested type + + + if (aType == CEikScrollBarFrame::TScrollBarType(EDoubleSpan)) + { + TRAP_IGNORE(CreateDoubleSpanScrollBarsL(ETrue,EFalse)); // by default a window owning + return; + } + + if (aType == CEikScrollBarFrame::TScrollBarType(EArrowHead)) + { + TRAP_IGNORE(CreateArrowHeadScrollBarsL()); + return; + } + } + } + +EXPORT_C CEikScrollBarFrame::TScrollBarType CEikScrollBarFrame::TypeOfHScrollBar() const + { + if (iExtension && iExtension->iH.iBar && + (iExtension->iH.iBar->ScrollBarType() == CEikScrollBar::TScrollBarType(EDoubleSpan))) + { + return EDoubleSpan; + } + else + { + return EArrowHead; + } + } + +EXPORT_C CEikScrollBarFrame::TScrollBarType CEikScrollBarFrame::TypeOfVScrollBar() const + { + if (iV.iBar && (iV.iBar->ScrollBarType() == CEikScrollBar::TScrollBarType(EDoubleSpan))) + { + return EDoubleSpan; + } + else + { + return EArrowHead; + } + } + +EXPORT_C TBool CEikScrollBarFrame::IsArrowHeadScrollBar(TInt /*aFlag*/) const + { + if (TypeOfVScrollBar() == TScrollBarType(EArrowHead)) + { + return ETrue; + } + else + { + return EFalse; + } + } + +EXPORT_C void CEikScrollBarFrame::CreateDoubleSpanScrollBarsL(TBool aWindowOwning, TBool aRemote) + { + CreateDoubleSpanScrollBarsL(aWindowOwning, aRemote, ETrue, ETrue); + } + +EXPORT_C void CEikScrollBarFrame::CreateDoubleSpanScrollBarsL(TBool aWindowOwning, TBool aRemote, TBool aVertical, TBool aHorizontal) + { + if (!TAknDoubleSpanScrollBarModel::ModelIsSupported()) + { + return; + } + + // This method should not delete the old scrollbars before it is sure that new + // one has been succesfully created. Create a temp variable here. + SBarData newVerticalScrollBar; + newVerticalScrollBar.iBar = NULL; + newVerticalScrollBar.iExternalScrollBarAttached = EFalse; + newVerticalScrollBar.iVisibility = iV.iVisibility; + + SBarData newHorizontalScrollBar; + newHorizontalScrollBar.iBar = NULL; + newHorizontalScrollBar.iExternalScrollBarAttached = EFalse; + if (iExtension) + newHorizontalScrollBar.iVisibility = iExtension->iH.iVisibility; + + if (aRemote && iExtension && iExtension->iParentWindow) + { + // try getting scrollbarframe from parent using mop supply mechanism + CEikScrollBarFrame* sbf = iExtension->iParentWindow->MopGetObject(sbf); + if (sbf) + { + newVerticalScrollBar.iBar = sbf->VerticalScrollBar(); + newVerticalScrollBar.iExternalScrollBarAttached = ETrue; + + newHorizontalScrollBar.iBar = sbf->HorizontalScrollBar(); + newHorizontalScrollBar.iExternalScrollBarAttached = ETrue; + + TInt err1 = KErrNone; + TInt err2 = KErrNone; + if (newVerticalScrollBar.iBar) + { + TRAP(err1, newVerticalScrollBar.iBar->AddExternalFrameL(this)); + } + + if (newHorizontalScrollBar.iBar) + { + TRAP(err2, newHorizontalScrollBar.iBar->AddExternalFrameL(this)); + } + + if (err1 || err2) + { + newVerticalScrollBar.iExternalScrollBarAttached = EFalse; + newVerticalScrollBar.iBar = NULL; + newHorizontalScrollBar.iExternalScrollBarAttached = EFalse; + newHorizontalScrollBar.iBar = NULL; + } + + User::LeaveIfError(err1); + User::LeaveIfError(err2); + + if (TypeOfVScrollBar() == EDoubleSpan) + { + if( AknLayoutUtils::PenEnabled() ) + { + // Correction. Giving null reference as parameter screws up the model values + newVerticalScrollBar.iModel = TAknDoubleSpanScrollBarModel(); + } + else + { + newVerticalScrollBar.iModel = TAknDoubleSpanScrollBarModel(0); + } + } + + if (TypeOfHScrollBar() == EDoubleSpan) + { + if( AknLayoutUtils::PenEnabled() ) + { + // Correction. Giving null reference as parameter screws up the model values + newHorizontalScrollBar.iModel = TAknDoubleSpanScrollBarModel(); + } + else + { + newHorizontalScrollBar.iModel = TAknDoubleSpanScrollBarModel(0); + } + } + + } + else + { + User::Leave(KErrNotFound); + } + } + else + { + // Create new vertical AknDoubleSpanScrollBar + newVerticalScrollBar.iBar = 0; + newVerticalScrollBar.iExternalScrollBarAttached=EFalse; + + CAknDoubleSpanScrollBar* verticalScrollBar = NULL; + + MEikScrollBarObserver* observer = NULL; + + if(AknLayoutUtils::PenEnabled()) + { + if(iExtension) + { + observer = iExtension->iScrollBarObserver; + } + } + + TInt scrollBarFlags = + ( ( iScrollBarFrameFlags & EEnableNudgeButtons ) ? + CEikScrollBar::EEnableNudgeButtons : 0 ) | + ( ( iScrollBarFrameFlags & EDisableExpandedTouchArea ) ? + CEikScrollBar::EDisableExpandedTouchArea : 0 ); + + if (aVertical) + { + verticalScrollBar = new(ELeave) CAknDoubleSpanScrollBar(ParentWindow()); + CleanupStack::PushL(verticalScrollBar); + verticalScrollBar->ConstructL( + aWindowOwning, observer ,ParentWindow(), + CAknScrollBar::EVertical, + KLongEnoughToCauseComponentsToBeCreated, + scrollBarFlags ); + CleanupStack::Pop(); // verticalScrollBar + } + newVerticalScrollBar.iBar = verticalScrollBar; + if( AknLayoutUtils::PenEnabled() ) + { + // Correction. Giving null reference as parameter screws up the model values + newVerticalScrollBar.iModel = TAknDoubleSpanScrollBarModel(); + } + else + { + newVerticalScrollBar.iModel = TAknDoubleSpanScrollBarModel(0); + } + + // Create new horizontal AknDoubleSpanScrollBar + newHorizontalScrollBar.iBar = 0; + newHorizontalScrollBar.iExternalScrollBarAttached=EFalse; + CAknDoubleSpanScrollBar* horizontalScrollBar = NULL; + + if (aHorizontal) + { + horizontalScrollBar = new(ELeave) CAknDoubleSpanScrollBar(ParentWindow()); + CleanupStack::PushL(horizontalScrollBar); + horizontalScrollBar->ConstructL( + aWindowOwning, observer ,ParentWindow(), + CAknScrollBar::EHorizontal, + KLongEnoughToCauseComponentsToBeCreated, + scrollBarFlags ); + CleanupStack::Pop(); // horizontalScrollBar + } + newHorizontalScrollBar.iBar = horizontalScrollBar; + if( AknLayoutUtils::PenEnabled() ) + { + // Correction. Giving null reference as parameter screws up the model values + newHorizontalScrollBar.iModel = TAknDoubleSpanScrollBarModel(); + } + else + { + newHorizontalScrollBar.iModel = TAknDoubleSpanScrollBarModel(0); + } + } + + TBool oldVerticalScrollbarExists = EFalse; + TBool oldHorizontalScrollbarExists = EFalse; + + if (iV.iBar) + oldVerticalScrollbarExists = ETrue; + + if (iExtension && iExtension->iH.iBar) + oldHorizontalScrollbarExists = ETrue; + + + if (oldVerticalScrollbarExists || oldHorizontalScrollbarExists) + { + // Remove old scroll bar + DeleteScrollBars(); + } + + iV = newVerticalScrollBar; + + if (iExtension) + iExtension->iH = newHorizontalScrollBar; + + } + + +EXPORT_C void CEikScrollBarFrame::Tile(TEikScrollBarModel* aVModel, TRect& aVScrollBarRect) + { + Tile(aVModel); + TRect tempRect(aVScrollBarRect); + if(aVScrollBarRect.Height() < 0 ) + { + aVScrollBarRect.iTl.iY = aVScrollBarRect.iBr.iY; + aVScrollBarRect.iBr.iY = tempRect.iTl.iY; + } + if(aVScrollBarRect.Width() < 0 ) + { + aVScrollBarRect.iTl.iX = aVScrollBarRect.iBr.iX; + aVScrollBarRect.iBr.iX = tempRect.iTl.iX; + } + if (iV.iBar && TypeOfVScrollBar() == EDoubleSpan && iV.iExternalScrollBarAttached==EFalse ) + { + CAknDoubleSpanScrollBar* scrollbar = static_cast (iV.iBar); + // check if fixed layout has been set + if (scrollbar->FixedLayoutRect().Size() == TSize(0,0)) + { + if (aVScrollBarRect != TRect(iV.iBar->Position(), iV.iBar->Size())) + { + iV.iBar->SetRect(aVScrollBarRect); + } + } + } + } + + +void CEikScrollBarFrame::DeleteScrollBars() + { + // + // Delete vertical scollbar + // + if(!iV.iExternalScrollBarAttached) + delete(iV.iBar); + else if (iV.iBar) + { + if (iExtension && iExtension->iParentWindow && iExtension->iParentWindow->IsVisible()) + { + // This test will be false if the app is being destroyed, making it unsafe to resize the CBA. + if (CCoeEnv::Static()->NormalFont()) + iV.iBar->MakeVisible(EFalse); + } + iV.iBar->RemoveExternalFrame(this); // calls back to DisconnectExternalScrollBar to null iV.iBar + __ASSERT_DEBUG(iV.iBar == NULL, SbfPanic(EFailedToRemoveExternalScrollBar)); + } + + // + // Delete horizontal scrollbar + // + if(iExtension && iExtension->iH.iBar) + { + if(!(iExtension->iH.iExternalScrollBarAttached)) + { + delete(iExtension->iH.iBar); + iExtension->iH.iBar = NULL; + } + else if (iExtension->iH.iBar) + { + if (iExtension && iExtension->iParentWindow && iExtension->iParentWindow->IsVisible()) + { + // This test will be false if the app is being destroyed, making it unsafe to resize the CBA. + if (CCoeEnv::Static()->NormalFont()) + iExtension->iH.iBar->MakeVisible(EFalse); + } + iExtension->iH.iBar->RemoveExternalFrame(this); // calls back to DisconnectExternalScrollBar to null iV.iBar + __ASSERT_DEBUG(iExtension->iH.iBar == NULL, SbfPanic(EFailedToRemoveExternalScrollBar)); + } + } + } + + +void CEikScrollBarFrame::CreateArrowHeadScrollBarsL() + { + CEikCba* cba=GetCurrentCba(); + if (cba) + { + // create arrow heads + TRAPD(err, cba->CreateArrowHeadScrollBarL()); + if (err) + { + iV.iExternalScrollBarAttached = EFalse; + iV.iBar = NULL; + return; + } + // delete old scroll bars + DeleteScrollBars(); + // returns the vertical scroll bar from the top scroll bar host + iV.iBar=cba->VScrollBarAsControl(); + iV.iExternalScrollBarAttached=ETrue; + TRAPD(err2, iV.iBar->AddExternalFrameL(this)); + if (err2) + { + iV.iExternalScrollBarAttached = EFalse; + iV.iBar = NULL; + } + } + } + +void CEikScrollBarFrame::CalcTheoreticalScrollBarVisibility(const TEikScrollBarModel* aVModel, const TEikScrollBarModel* aHModel) + { + // assume no scrollbars to start with + iScrollBarFrameFlags&=(~EDisplayVScrollBar); + iScrollBarFrameFlags&=(~EDisplayHScrollBar); + + TBool verticalScrollBarUseful = EFalse; + TBool horizontalScrollBarUseful = EFalse; + + if (aVModel) + { + switch(TypeOfVScrollBar()) + { + case EDoubleSpan: + { + if (aVModel->ScrollBarModelType() == TEikScrollBarModel::EAknDoubleSpanScrollBarModel) + { + //const TAknDoubleSpanScrollBarModel* model = static_cast (aVModel); + //verticalScrollBarUseful = (model->FocusPosition() < model->ScrollSpan()) && (model->WindowSize() <= model->ScrollSpan()); + verticalScrollBarUseful = ETrue; // S60 style says double span scrollbar is always shown if visibility is EAuto + } + 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("CEikScrollBarFrame: Please, use TAknDoubleSpanScrollBarModel instead of TEikScrollBarModel")); + //#endif + // In most cases we can work with the TEikScrollBarModel model. + //verticalScrollBarUseful = (aVModel->iThumbPosition < aVModel->iScrollSpan) && (aVModel->iThumbSpan <= aVModel->iScrollSpan); + verticalScrollBarUseful = ETrue; // S60 style says double span scrollbar is always shown if visibility is EAuto + } + break; + } + + case EArrowHead: // fallthrough + default: + { + verticalScrollBarUseful = aVModel->ScrollBarUseful(); + break; + } + } + } + + if (aHModel) + { + switch(TypeOfHScrollBar()) + { + case EDoubleSpan: // by default only double span is supported as horizontal scrollbar + default: + { + if (aHModel->ScrollBarModelType() == TEikScrollBarModel::EAknDoubleSpanScrollBarModel) + { + //const TAknDoubleSpanScrollBarModel* model = static_cast (aHModel); + //horizontalScrollBarUseful = (model->FocusPosition() < model->ScrollSpan()) && (model->WindowSize() <= model->ScrollSpan()); + horizontalScrollBarUseful = ETrue; // S60 style says double span scrollbar is always shown if visibility is EAuto + } + 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("CEikScrollBarFrame: Please, use TAknDoubleSpanScrollBarModel instead of TEikScrollBarModel")); + //#endif + // In most cases we can work with the TEikScrollBarModel model. + //horizontalScrollBarUseful = (aHModel->iThumbPosition < aHModel->iScrollSpan) && (aHModel->iThumbSpan <= aVModel->iScrollSpan); + horizontalScrollBarUseful = ETrue; // S60 style says double span scrollbar is always shown if visibility is EAuto + } + break; + } + } + } + + + // Decide visibility for vertical scrollbar + if ( (iV.iVisibility==EOn) || ( (iV.iVisibility==EAuto)&&(verticalScrollBarUseful) ) ) + { + iScrollBarFrameFlags|=EDisplayVScrollBar; + } + + // Decide visibility for horizontal scrollbar + if (iExtension && (iExtension->iH.iVisibility==EOn || (iExtension->iH.iVisibility==EAuto && horizontalScrollBarUseful))) + { + iScrollBarFrameFlags|=EDisplayHScrollBar; + } + } + +EXPORT_C CEikScrollBarFrame::TScrollBarVisibility CEikScrollBarFrame::ScrollBarVisibility(CEikScrollBar::TOrientation aOrientation) const + { + if (aOrientation == CEikScrollBar::EVertical) + { + return iV.iVisibility; + } + else + { + if (iExtension) + { + return iExtension->iH.iVisibility; + } + else + { + return EOff; + } + + } + } + +EXPORT_C void CEikScrollBarFrame::Tile(TEikScrollBarModel* aHModel, TEikScrollBarModel* aVModel) + { + GetScrollBars(EFalse); + CalcTheoreticalScrollBarVisibility(aVModel,aHModel); + + if (iV.iVisibility!=EOff) + iV.iModel = *aVModel; + + MakeSBarVisible(iV, iScrollBarFrameFlags&EDisplayVScrollBar); + + if (iExtension && iExtension->iH.iBar) + { + if (iExtension->iH.iVisibility!=EOff) + iExtension->iH.iModel = *aHModel; + + MakeSBarVisible(iExtension->iH, iScrollBarFrameFlags&EDisplayHScrollBar); + } + + } + +EXPORT_C TInt CEikScrollBarFrame::DrawBackground(TBool aDrawHorizontal, TBool aDrawVertical) + { + // The double span scrollbar only supports backgroun drawing flag + if(TypeOfHScrollBar() != EDoubleSpan && TypeOfVScrollBar() != EDoubleSpan) + { + return KErrNotSupported; + } + + if(iV.iBar && (TypeOfVScrollBar() == EDoubleSpan)) + { + CAknDoubleSpanScrollBar* scrollbar = static_cast (iV.iBar); + scrollbar->DrawBackground(aDrawVertical); + } + + if(iExtension && iExtension->iH.iBar && (TypeOfHScrollBar() == EDoubleSpan)) + { + CAknDoubleSpanScrollBar* scrollbar = static_cast (iExtension->iH.iBar); + scrollbar->DrawBackground(aDrawHorizontal); + } + + return KErrNone; + } + +EXPORT_C TInt CEikScrollBarFrame::DrawBackgroundState(TBool& aDrawHorizontal, TBool& aDrawVertical) + { + // The double span scrollbar only supports backgroun drawing flag + + if(iV.iBar && (TypeOfVScrollBar() == EDoubleSpan)) + { + CAknDoubleSpanScrollBar* scrollbar = static_cast (iV.iBar); + aDrawVertical = scrollbar->DrawBackgroundState(); + } + + if(iExtension && iExtension->iH.iBar && (TypeOfHScrollBar() == EDoubleSpan)) + { + CAknDoubleSpanScrollBar* scrollbar = static_cast (iExtension->iH.iBar); + aDrawHorizontal = scrollbar->DrawBackgroundState(); + } + + if(TypeOfHScrollBar() != EDoubleSpan && TypeOfVScrollBar() != EDoubleSpan) + { + return KErrNotSupported; + } + + return KErrNone; + } + +CEikScrollBar* CEikScrollBarFrame::HorizontalScrollBar() const + { + if (iExtension) + return iExtension->iH.iBar; + else + return NULL; + } + + + +// For Cba Scrollbar frame + +CEikCbaScrollBarFrame::CEikCbaScrollBarFrame(CCoeControl* aParentWindow, MEikScrollBarObserver* /*aObserver*/, TBool /*aPreAlloc*/) + { + SetParentWindow(aParentWindow); + } + +void CEikCbaScrollBarFrame::ConstructL() + { + iV.iBar = 0; + iV.iExternalScrollBarAttached=EFalse; + + // We construct CEikScrollBar instance here, because it doesn't create bitmaps -> faster + // and save RAM. If CBAs are really needed, then we replace CEikScrollBar with + // CAknArrowHeadScrollBar instance at SwitchArrowHeadScrollBarL method. + iV.iBar = new(ELeave) CEikScrollBar(); + iV.iBar->ConstructL(NULL,ParentWindow(),CAknScrollBar::EVertical,KLongEnoughToCauseComponentsToBeCreated,0); + } + +// Delete CEikScrollBar instance and replace it with actual arrow head scroll bar +void CEikCbaScrollBarFrame::SwitchToArrowHeadScrollBarL() + { + delete(iV.iBar); + iV.iBar = 0; + iV.iExternalScrollBarAttached=EFalse; + iV.iBar = new(ELeave) CAknArrowHeadScrollBar(ParentWindow()); + iV.iBar->ConstructL(NULL,ParentWindow(),CAknScrollBar::EVertical,KLongEnoughToCauseComponentsToBeCreated,0); + } +