// EIKSCRLB.CPP
//
// Copyright (c) 1997-1999 Symbian Ltd.  All rights reserved.
//

#include <eikscrlb.h>
#include <eikthumb.h>
#include <eikpanic.h>
#include <eikenv.h>

#include <eikcolor.h>

const TInt KEikScrollBarBorderWidth=1;

/*#define KShaftColor TRgb1in4DitheredGray
#define KShaftDimmedColor KRgbWhite
#define KShaftPressedColor KDarkGrey
#define KNoShaftOrThumbColor KRgbWhite*/

const TInt KEikScrollButtonInitialDelay=600000;
const TInt KEikScrollNudgeButtonRepeat=20000;
const TInt KEikScrollPageButtonRepeat=30000;
const TInt KEikScrollHomeEndButtonRepeat=30000;

//
// TEikScrollBarModel class
//

EXPORT_C TBool TEikScrollBarModel::operator==(const TEikScrollBarModel aModel) const
	{
	return ((iScrollSpan==aModel.iScrollSpan)&(iThumbSpan==aModel.iThumbSpan)&(iThumbPosition==aModel.iThumbPosition));
	}

EXPORT_C TEikScrollBarModel::TEikScrollBarModel(TInt aScrollSpan,TInt aThumbSpan,TInt aThumbPosition)
	: iScrollSpan(aScrollSpan),
	iThumbSpan(aThumbSpan),
	iThumbPosition(aThumbPosition)
	{}

EXPORT_C TBool TEikScrollBarModel::ScrollBarUseful() const
	{
	return iThumbSpan<iScrollSpan;
	}

EXPORT_C TInt TEikScrollBarModel::MaxThumbPos() const
	{
	return iScrollSpan-iThumbSpan;
	}

EXPORT_C void TEikScrollBarModel::CheckBounds()
// Ensure the thumbposition remains within it's valid range
	{
	iThumbPosition=Max(0,Min(iThumbPosition,iScrollSpan-iThumbSpan));
	}

/* nobody using this
EXPORT_C void TEikScrollBarModel::SetModelFromEndValues(TInt aAbove,TInt aBelow,TInt aTotal)
// set the scrollbar model using a different method
	{
	iScrollSpan=aTotal;
	iThumbSpan=aTotal-aAbove-aBelow;
	iThumbPosition=aAbove;
	}
*/

//
// CEikScrollBar class
//

EXPORT_C CEikScrollBar::~CEikScrollBar()
// Destrutor
    {
	delete(iThumb);
	delete(iButtons.iIncreaseNudge);
	delete(iButtons.iDecreaseNudge);
	delete(iButtons.iIncreasePage);
	delete(iButtons.iDecreasePage);
	delete(iButtons.iHome);															  
	delete(iButtons.iEnd);
    }

EXPORT_C CEikScrollBar::CEikScrollBar()
	: CEikBorderedControl(TEikBorder(TEikBorder::ESingleBlack))
// Default constuctor
	{
	__DECLARE_NAME(_S("CEikButtonBase"));
	iBorder.SetType(TEikBorder::ESingleBlack);
	SetNonFocusing();
	}

EXPORT_C void CEikScrollBar::ConstructL(MEikScrollBarObserver* aScrollBarObserver,const CCoeControl* aParent,
										TOrientation aOrientation,TInt aLength,TInt aScrollBarFlags)
// Second-phase construction
    {
    CreateWindowL(aParent);
    iScrollBarObserver=aScrollBarObserver;
	SetObserver(aParent->Observer());
    iOrientation=aOrientation;
	iScrollBarFlags=aScrollBarFlags;
 	if ((iScrollBarFlags&KButtonPositionMask)==0x0)
		iScrollBarFlags|=EButtonsAtEndOfShaft;
	DoSetLengthL(aLength);
    Window().SetPointerGrab(ETrue); 
    EnableDragEvents();
    }

EXPORT_C void CEikScrollBar::HandlePointerEventL(const TPointerEvent& aPointerEvent) 
// Determine the pointer event type & position and take appropriate action
   {
   if ((iModel.iScrollSpan<=iModel.iThumbSpan))
        return;
    TPointerEvent::TType type=aPointerEvent.iType;
	TInt pos=(iOrientation==EHorizontal) ? aPointerEvent.iPosition.iX : aPointerEvent.iPosition.iY;
    if (type==TPointerEvent::EButton1Down)
        {// Find out where the left down was
		if (pos>=iShaftStart&&pos<=iShaftEnd)
			// not on a button
			{
			if (iScrollBarDisplayFlags&(EEikScrollBarNoShaftOrThumb|EEikScrollBarShaftButNoThumb))
				return;
			if (pos<iThumbPos)
				iPointerDownOn=EDecreaseShaft;
			else if (pos<iThumbPos+iThumbLength)
				iPointerDownOn=EThumb;
			else
				iPointerDownOn=EIncreaseShaft;
			}
		else
			{// on a button
			iPointerDownOn=ResolveButtonPress(pos);
			}
        }
 	TPointerDownOn lastPointerDownOn=iPointerDownOn;
   	if (type==TPointerEvent::EButton1Up)
        iPointerDownOn=ENone;
	// Respond to pointer event
	switch (iPointerDownOn)
		{
	case EDecreaseShaft:
	case EIncreaseShaft:
		if (IsDimmed())
			return;
		HandleShaftEventL(aPointerEvent,lastPointerDownOn);
		break;
	case EThumb:
		if (iShaftEnd-iShaftStart<=iThumbLength)
			return; // for cases when scrollbar is too small to represent model
		switch (type)
			{
        default:
            break;
		case TPointerEvent::EButton1Down:
			iPointerOffsetFromThumb=pos-iThumbPos;
			iThumb->SetDragState(ETrue);
			iThumb->DrawDragStateNow();
			break;
		case TPointerEvent::EDrag:
			TInt newPos=pos-iPointerOffsetFromThumb;
			if (newPos<iShaftStart)
				newPos=iShaftStart;
			else if (newPos>iShaftEnd-iThumbLength)
				newPos=iShaftEnd-iThumbLength;
			TInt oldPos=iThumbPos;
			MoveThumbToPixel(newPos);
			iModel.iThumbPosition=CalcThumbModelPos();
			CheckAutoButtonDimming();
			if (newPos!=oldPos)
				ReportScrollEventL(iOrientation==EHorizontal ? EEikScrollThumbDragHoriz : EEikScrollThumbDragVert);
			break;
			}
		break;
	// buttons
	case EDecreaseNudgeButton:
		HandleButtonEventL(aPointerEvent,iButtons.iDecreaseNudge);
		break;
	case EIncreaseNudgeButton:
		HandleButtonEventL(aPointerEvent,iButtons.iIncreaseNudge);
		break;
	case EDecreasePageButton:
		HandleButtonEventL(aPointerEvent,iButtons.iDecreasePage);
		break;
	case EIncreasePageButton:
		HandleButtonEventL(aPointerEvent,iButtons.iIncreasePage);
		break;
	case EHomeButton:
		HandleButtonEventL(aPointerEvent,iButtons.iHome);
		break;
	case EEndButton:
		HandleButtonEventL(aPointerEvent,iButtons.iEnd);
		break;
	case ENone:
		// button released
		switch (lastPointerDownOn)
			{
        default:
            break;
		case EThumb:
			// clear thumb's emphasis
			iThumb->SetDragState(EFalse);
			iThumb->DrawDragStateNow();
			ReportScrollEventL(iOrientation==EHorizontal ? EEikScrollThumbReleaseHoriz : EEikScrollThumbReleaseVert);
			break;
		// Release buttons
		case EDecreaseNudgeButton:
			iButtons.iDecreaseNudge->HandlePointerEventL(aPointerEvent);
			break;
		case EIncreaseNudgeButton:
			iButtons.iIncreaseNudge->HandlePointerEventL(aPointerEvent);
			break;
		case EDecreasePageButton:
			iButtons.iDecreasePage->HandlePointerEventL(aPointerEvent);
			break;
		case EIncreasePageButton:
			iButtons.iIncreasePage->HandlePointerEventL(aPointerEvent);
			break;
		case EHomeButton:
			iButtons.iHome->HandlePointerEventL(aPointerEvent);
			break;
		case EEndButton:
			iButtons.iEnd->HandlePointerEventL(aPointerEvent);
			break;
		// clear shaft highlight
		case EIncreaseShaft:
		case EDecreaseShaft:
			if (IsDimmed())
				return;
			HandleShaftEventL(aPointerEvent,lastPointerDownOn);
			break;
			}
		break;
		}
    }

EXPORT_C void CEikScrollBar::ActivateL()
	{
	CCoeControl::ActivateL();
	if (iThumb)
		iThumb->ActivateL();
	if (iButtons.iIncreaseNudge)
		iButtons.iIncreaseNudge->ActivateL();
	if (iButtons.iDecreaseNudge)
		iButtons.iDecreaseNudge->ActivateL();
	if (iButtons.iIncreasePage)
		iButtons.iIncreasePage->ActivateL();
	if (iButtons.iDecreasePage)
		iButtons.iDecreasePage->ActivateL();
	if (iButtons.iHome)
		iButtons.iHome->ActivateL();
	if (iButtons.iEnd)
		iButtons.iEnd->ActivateL();
	}

EXPORT_C void CEikScrollBar::SetDimmed(TBool aDimmed)
// Set the dimmed state of the scrollbar - will NOT redraw
	{
	CCoeControl::SetDimmed(aDimmed);
	if (aDimmed)
		SetAllButtonsDimmed(ETrue);
	else
		CheckAutoButtonDimming(ENoDrawNow);
	if (iThumb)
		iThumb->SetDimmed(aDimmed);
	}

EXPORT_C void CEikScrollBar::SetLengthL(TInt aLength)
// Change the scrollbar's length.  Will redraw
	{
	if (aLength==iLength)
		return;
    DoSetLengthL(aLength);
	if (iScrollBarFlags&ENoComponentsToDisplay)
		return;
	UpdateButtonsL();
	DrawShaftNow();
	DrawButtonsNow(EAll);
	MoveResizeThumbL(ERedrawShaft);
	}

EXPORT_C void CEikScrollBar::SetModelL(const TEikScrollBarModel* aModel)
// Change the scrollbar model and move/resize the thumb appropriately
    {
	if (*aModel==iModel)
		return;
	DoSetModel(aModel);
	if (iThumb)
    	MoveResizeThumbL();
	CheckAutoButtonDimming();
    }

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
    {
	const TBool modelChanged=(*aModel!=iModel);
	const TBool lengthChanged=(aLength!=iLength);
	TShaftRedrawRequired redraw=ENoRedrawRequired;
	if ((!lengthChanged)&&(!modelChanged))
		return;
	if (modelChanged)
		DoSetModel(aModel);
	if (lengthChanged)
		{
		redraw=ERedrawShaft;
		DoSetLengthL(aLength);
		UpdateButtonsL();
		DrawShaftNow();
		DrawButtonsNow(EAll);
		}
	MoveResizeThumbL(redraw);
	if (modelChanged)
		CheckAutoButtonDimming();
    }

EXPORT_C void CEikScrollBar::SetModelThumbPosition(TInt aThumbPos)
// Change just the thumb position - less calculation than the whole model
	{
	iModel.iThumbPosition=aThumbPos;
	CheckModelBounds();
	if (iThumb)
		MoveThumbToPixel(CalcThumbPixelPos());
	CheckAutoButtonDimming();
	}

/* nobody using this
EXPORT_C void CEikScrollBar::AdjustOnlyModelThumbPosition(const TEikScrollBarModel* aModel)
	{
	//
	// Sets iModel's thumb position in proportion to aModel keeping thumbspan fixed
	// Note: MaxThumbPos=ScrollRange
	//
	TInt64 incomingThumbPos=aModel->iThumbPosition;
	TInt64 incomingScrollRange=aModel->MaxThumbPos();
	TInt64 thisScrollRange=iModel.MaxThumbPos();
	TInt64 thumbPosition=(incomingScrollRange==0) ? TInt64(0) : (thisScrollRange*incomingThumbPos)/incomingScrollRange;
	SetModelThumbPosition(thumbPosition.Low());
	}
*/

EXPORT_C TInt CEikScrollBar::ThumbPosition() const
// Retrun the model's thumb position (eg in response to a scroll event)
    {
    return(iModel.iThumbPosition);
    }

EXPORT_C TInt CEikScrollBar::ScrollBarBreadth() const
// returns the height of a horizontal scrollbar or width of a vertical scrollbar
	{
	if (iOrientation==EHorizontal)
		return iSize.iHeight;
	return iSize.iWidth;
	}

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)
	{
	if (!(aScrollBarFlags&EEikScrollBarNoShaftOrThumb))
		return (KEikScrollBarBorderWidth<<1);	// nearly always visible with shaft
	// no shaft
	const TInt buttonSide=EScrollbarWidth;
	return (buttonSide<<1);
	}

EXPORT_C void CEikScrollBar::SetDecreaseButtonsDimmed(TBool aDimmed) 	 
// Dim out the decrease buttons
	{
	if (aDimmed)
		iScrollBarFlags|=EDecreaseButtonsDimmed;
	else
		iScrollBarFlags&=(~EDecreaseButtonsDimmed);
	if (!(iScrollBarDisplayFlags&EEikScrollBarNoNudgeButtons))
		iButtons.iDecreaseNudge->SetDimmed(aDimmed);
	if (iScrollBarDisplayFlags&EEikScrollBarHasPageButtons)
		iButtons.iDecreasePage->SetDimmed(aDimmed);
	if (iScrollBarDisplayFlags&EEikScrollBarHasHomeEndButtons)
		iButtons.iHome->SetDimmed(aDimmed);
	}

EXPORT_C void CEikScrollBar::SetIncreaseButtonsDimmed(TBool aDimmed) 	
// Dim out the increase buttons
	{
	if (aDimmed)
		iScrollBarFlags|=EIncreaseButtonsDimmed;
	else
		iScrollBarFlags&=(~EIncreaseButtonsDimmed);
	if (!(iScrollBarDisplayFlags&EEikScrollBarNoNudgeButtons))
		iButtons.iIncreaseNudge->SetDimmed(aDimmed);
	if (iScrollBarDisplayFlags&EEikScrollBarHasPageButtons)
		iButtons.iIncreasePage->SetDimmed(aDimmed);
	if (iScrollBarDisplayFlags&EEikScrollBarHasHomeEndButtons)
		iButtons.iEnd->SetDimmed(aDimmed);
	}

EXPORT_C void CEikScrollBar::SetAllButtonsDimmed(TBool aDimmed) 	
// Dim out all buttons
	{
	SetDecreaseButtonsDimmed(aDimmed);
	SetIncreaseButtonsDimmed(aDimmed);
	}

void CEikScrollBar::CreateRequiredComponentsL()
// Allocates and constructs all the required components of the scrollbar
	{
	TBool horiz=(iOrientation==EHorizontal);
	if (!(iScrollBarFlags&(EEikScrollBarNoShaftOrThumb|EEikScrollBarShaftButNoThumb)))
		{
		if (iThumb==NULL)
			{
			iThumb=new(ELeave) CEikScrollThumb((CEikScrollThumb::TOrientation)iOrientation);
			iThumb->SetContainerWindowL(*this);
			}
		}
	if (!(iScrollBarDisplayFlags&EEikScrollBarNoNudgeButtons))
		{
		CreateButtonL(iButtons.iDecreaseNudge,horiz ? CEikScrollButton::ENudgeLeft : CEikScrollButton::ENudgeUp);
		CreateButtonL(iButtons.iIncreaseNudge,horiz ? CEikScrollButton::ENudgeRight : CEikScrollButton::ENudgeDown);
		}
	if (iScrollBarDisplayFlags&EEikScrollBarHasPageButtons)
		{
		CreateButtonL(iButtons.iDecreasePage,horiz ? CEikScrollButton::EPageLeft : CEikScrollButton::EPageUp);
		CreateButtonL(iButtons.iIncreasePage,horiz ? CEikScrollButton::EPageRight : CEikScrollButton::EPageDown);
		}
	if (iScrollBarDisplayFlags&EEikScrollBarHasHomeEndButtons)
		{
		CreateButtonL(iButtons.iHome,horiz ? CEikScrollButton::EHome : CEikScrollButton::ETop);
		CreateButtonL(iButtons.iEnd,horiz ? CEikScrollButton::EEnd : CEikScrollButton::EBottom);
		}
	}

void CEikScrollBar::CreateButtonL(CEikScrollButton*& aButton,CEikScrollButton::TType aType)
// Create the appropriate button
	{
	if (aButton)
		return;
	CEikScrollButton* button=new(ELeave) CEikScrollButton(aType);
	CleanupStack::PushL(button);
	button->SetContainerWindowL(*this);
	SetButtonPositionL(button);
	CleanupStack::Pop(); // button
	aButton=button;
	}

void CEikScrollBar::DestroyButton(CEikScrollButton*& aButton)
// destroy a button
	{
	delete aButton;
	aButton=NULL;
	}

void CEikScrollBar::HandleShaftEventL(const TPointerEvent& aPointerEvent,TPointerDownOn aLastPointerDownOn)
// React to pointer events in the shaft area (not including thumb)
	{
	TPointerEvent::TType type=aPointerEvent.iType;
	TRect rect;
	GetShaftRect(rect);
	TRect fillRect=rect;
	fillRect.Shrink(KEikScrollBarBorderWidth,KEikScrollBarBorderWidth);
	switch (aLastPointerDownOn)
		{
    default:
        break;
	case EDecreaseShaft:
		if (iOrientation==EHorizontal)
			fillRect.iBr.iX=rect.iBr.iX=iThumbPos;
		else
			fillRect.iBr.iY=rect.iBr.iY=iThumbPos;
		break;
	case EIncreaseShaft:
		if (iOrientation==EHorizontal)
			fillRect.iTl.iX=rect.iTl.iX=iThumbPos+iThumbLength;
		else
			fillRect.iTl.iY=rect.iTl.iY=iThumbPos+iThumbLength;
		break;
		}
	ActivateGc();
	CWindowGc& gc=SystemGc();
	TRgb color= iEikonEnv->ControlColor(((type==TPointerEvent::EButton1Up)? EEikColorScrollBarShaft : EEikColorScrollBarShaftPressed), *this); // (type==TPointerEvent::EButton1Up)? KEikScrollBarShaftColor : KEikScrollBarShaftPressedColor;
	if (type==TPointerEvent::EButton1Up)
		{
		gc.SetBrushColor(color);
		gc.Clear(fillRect);
		DeactivateGc();
		}
	else if (fillRect.Contains(aPointerEvent.iPosition))
		{
		TInt buttonRepeat=KEikScrollPageButtonRepeat;
		if (type==TPointerEvent::EButton1Down)
			buttonRepeat=KEikScrollButtonInitialDelay;
		Window().RequestPointerRepeatEvent(buttonRepeat,fillRect);
		gc.SetBrushColor(color);
		gc.Clear(fillRect);
		DeactivateGc();
		switch (aLastPointerDownOn)
			{
		case EDecreaseShaft:
			ReportScrollEventL(iOrientation==EHorizontal ? EEikScrollPageLeft : EEikScrollPageUp);
			break;
		case EIncreaseShaft:
			ReportScrollEventL(iOrientation==EHorizontal ? EEikScrollPageRight : EEikScrollPageDown);
			break;
        default:
            break;
			}
		}
	else
		{
		DeactivateGc();
		}
	}

void CEikScrollBar::HandleButtonEventL(const TPointerEvent& aPointerEvent ,CEikScrollButton* aButton)
	//
	// react to pointer events on buttons
	//
	{
	if (aButton->IsDimmed())
		return;
	TInt buttonRepeat=KEikScrollNudgeButtonRepeat;
	aButton->HandlePointerEventL(aPointerEvent);
	TEikScrollEvent scrollEvent=EEikScrollUp;
	if (!(aButton->Rect().Contains(aPointerEvent.iPosition)))
		return;
	switch (iPointerDownOn)
		{
    default:
        break;
	case EDecreaseNudgeButton:
		scrollEvent=(iOrientation==EHorizontal ? EEikScrollLeft : EEikScrollUp);
		break;
	case EIncreaseNudgeButton:
		scrollEvent=(iOrientation==EHorizontal ? EEikScrollRight : EEikScrollDown);
		break;
	case EDecreasePageButton:
		scrollEvent=(iOrientation==EHorizontal ? EEikScrollPageLeft : EEikScrollPageUp);
		buttonRepeat=KEikScrollPageButtonRepeat;
		break;
	case EIncreasePageButton:
		scrollEvent=(iOrientation==EHorizontal ? EEikScrollPageRight : EEikScrollPageDown);
		buttonRepeat=KEikScrollPageButtonRepeat;
		break;
	case EHomeButton:
		scrollEvent=(iOrientation==EHorizontal ? EEikScrollHome : EEikScrollTop);
		buttonRepeat=KEikScrollHomeEndButtonRepeat;
		break;
	case EEndButton:
		scrollEvent=(iOrientation==EHorizontal ? EEikScrollEnd : EEikScrollBottom);
		buttonRepeat=KEikScrollHomeEndButtonRepeat;
		break;
		}
	if (aPointerEvent.iType==TPointerEvent::EButton1Down)
		buttonRepeat=KEikScrollButtonInitialDelay;
	Window().RequestPointerRepeatEvent(buttonRepeat,aButton->Rect());
	ReportScrollEventL(scrollEvent);
	}

EXPORT_C void CEikScrollBar::Draw(const TRect& /*aRect*/) const
// Draw the whole scrollbar
    {
	CWindowGc& gc=SystemGc();
	DrawButtons(EAll);
	DrawShaft(gc);
	DrawThumbInShaft(gc);
    }

void CEikScrollBar::DrawButtons(TWhichButtons aWhich) const
	//
	// Draw the necessary buttons
	//
	{
	TRect dummy;	// gets ignored in CEikScrollButton::Draw
	if (!(iScrollBarDisplayFlags&EEikScrollBarNoNudgeButtons))
		{
		if (aWhich!=EIncreaseOnly)
			iButtons.iDecreaseNudge->Draw(dummy);
		if (aWhich!=EDecreaseOnly)
			iButtons.iIncreaseNudge->Draw(dummy);
		}
	if (iScrollBarDisplayFlags&EEikScrollBarHasPageButtons)
		{
		if (aWhich!=EIncreaseOnly)
			iButtons.iDecreasePage->Draw(dummy);
		if (aWhich!=EDecreaseOnly)
			iButtons.iIncreasePage->Draw(dummy);
		}
	if (iScrollBarDisplayFlags&EEikScrollBarHasHomeEndButtons)
		{
		if (aWhich!=EIncreaseOnly)
			iButtons.iHome->Draw(dummy);
		if (aWhich!=EDecreaseOnly)
			iButtons.iEnd->Draw(dummy);
		}
	}

void CEikScrollBar::DrawButtonsNow(TWhichButtons aWhich) const
	{
	ActivateGc();
	DrawButtons(aWhich);
	DeactivateGc();
	} 

void CEikScrollBar::DrawShaft(CWindowGc& aGc) const
// Draw the shaft or a blank rectangle if no shaft present and scrollbar is too big for buttons
	{
	TRect rect;
	GetShaftRect(rect);
	if (iScrollBarDisplayFlags&EEikScrollBarNoShaftOrThumb)
		{
		aGc.SetBrushColor(iEikonEnv->ControlColor(EEikColorScrollBarNoShaftOrThumb, *this)); //KEikScrollBarNoShaftOrThumbColor);
		aGc.Clear(rect);
		}
	else
		{
		iBorder.Draw(aGc,rect);
		if (iScrollBarDisplayFlags&EEikScrollBarShaftButNoThumb)
			{// Shaft not redrawn by DrawThumbInShaft() in this case
			rect=iBorder.InnerRect(rect);;
			const TRgb shaftColor= iEikonEnv->ControlColor(((IsDimmed())? EEikColorScrollBarShaftDimmed : EEikColorScrollBarShaft), *this); //KEikScrollBarShaftDimmedColor : KEikScrollBarShaftColor;
			aGc.SetBrushColor(shaftColor);
			aGc.Clear(rect);
			}
		}
	}

void CEikScrollBar::DrawShaftNow() const
	{
	ActivateGc();
	CWindowGc& gc=SystemGc();
	DrawShaft(gc);
	DeactivateGc();
	}

void CEikScrollBar::DrawThumbInShaft(CWindowGc& aGc) const
// Draw the thumb in the shaft and fill shaft around thumb in a flicker free way
	{
	if (iScrollBarDisplayFlags&(EEikScrollBarNoShaftOrThumb|EEikScrollBarShaftButNoThumb))
		return;
	TRgb shaftColor=iEikonEnv->ControlColor(((IsDimmed())? EEikColorScrollBarShaftDimmed : EEikColorScrollBarShaft), *this); //(IsDimmed())? KEikScrollBarShaftDimmedColor : KEikScrollBarShaftColor;
    TRect shaftRect;
	GetShaftRect(shaftRect);
	shaftRect.Shrink(KEikScrollBarBorderWidth,KEikScrollBarBorderWidth);
	// draw shaft before thumb
	TRect rect=shaftRect;
	TInt& endOfShaftBeforeThumb=(iOrientation==EHorizontal)? rect.iBr.iX : rect.iBr.iY;
	endOfShaftBeforeThumb=iThumbPos;
	aGc.SetBrushColor(shaftColor);
	aGc.Clear(rect);
	// draw shaft after thumb
	rect=shaftRect;
	TInt& startOfShaftAfterThumb=(iOrientation==EHorizontal)? rect.iTl.iX : rect.iTl.iY;
	startOfShaftAfterThumb=iThumbPos+iThumbLength;
	aGc.SetBrushColor(shaftColor);
	aGc.Clear(rect);
	iThumb->Draw(rect);
	}

void CEikScrollBar::DrawThumbInShaftNow() const
	{
	ActivateGc();
	CWindowGc& gc=SystemGc();
	DrawThumbInShaft(gc);
	DeactivateGc();
	}

void CEikScrollBar::MoveResizeThumbL(TShaftRedrawRequired aShaftRedrawRequired)
// Set the thumb's size and position according to the (assumed new) values
// of iScrollSpan and iThumbSpan.
    {
	if (iScrollBarDisplayFlags&(EEikScrollBarNoShaftOrThumb|EEikScrollBarShaftButNoThumb))
		{
		iThumbLength=iThumbPos=0;
		return;
		}
	TInt thumbLength=iThumbLength;
	iThumbLength=iShaftEnd-iShaftStart;
	TInt scrollRange=iModel.iScrollSpan-iModel.iThumbSpan;
	if (scrollRange>0 && iModel.iScrollSpan)
		{
		iThumbLength*=iModel.iThumbSpan;
		iThumbLength/=iModel.iScrollSpan;
		}
	if (iThumbLength<EMinThumbLength)
		iThumbLength=EMinThumbLength;
	TInt thumbPos=CalcThumbPixelPos();
	if (aShaftRedrawRequired==ERedrawShaft)
		goto redrawShaft;
	else if (thumbLength==iThumbLength)
		MoveThumbToPixel(thumbPos);
	else
redrawShaft:
		{
		iThumbPos=thumbPos;
		NewThumbAtPixelL();
		}
	iThumbPos=thumbPos;
    }

void CEikScrollBar::MoveThumbToPixel(TInt aPos)
// Move thumb to pixel position aPos.
	{
	if (aPos==iThumbPos)
		return;
	ActivateGc();
	TPoint newThumbPos=iThumb->Position();
	TInt offset=aPos-iThumbPos;
	TPoint scrollOffset;
	if (iOrientation==EHorizontal)
		{
		newThumbPos.iX=aPos;
		scrollOffset.iX=offset;
		}
	else
		{
		newThumbPos.iY=aPos;
		scrollOffset.iY=offset;
		}
	TRect shaftRedrawArea=iThumb->Rect();
	if (aPos>iThumbPos)
		{// increase
		if (iOrientation==EHorizontal)
			shaftRedrawArea.iBr.iX=shaftRedrawArea.iTl.iX+offset;
		else
			shaftRedrawArea.iBr.iY=shaftRedrawArea.iTl.iY+offset; 
		goto doScroll;
		}
	else if (iThumbPos>aPos)
		{// decrease
		if (iOrientation==EHorizontal)
			shaftRedrawArea.iTl.iX=shaftRedrawArea.iBr.iX+offset;
		else
			shaftRedrawArea.iTl.iY=shaftRedrawArea.iBr.iY+offset;
doScroll:
		Window().Scroll(scrollOffset,iThumb->Rect());
		RedrawShaft(shaftRedrawArea);
		iThumb->SetPosition(newThumbPos);
		}
    iThumbPos=aPos;
	DeactivateGc();
	}

void CEikScrollBar::RedrawShaft(const TRect& aRect) const
// clears the shaft intersecting with aRect, redrawing the end lines if necessary
	{
	TRect rect=aRect;
	TRgb shaftColor=iEikonEnv->ControlColor(((IsDimmed())? EEikColorScrollBarShaftDimmed : EEikColorScrollBarShaft), *this); //(IsDimmed())? KEikScrollBarShaftDimmedColor : KEikScrollBarShaftColor;
	CWindowGc& gc=SystemGc();
	gc.SetPenColor(iEikonEnv->Color(EEikColorScrollBarBorder)); //KEikScrollBarBorderColor);
	// first check endpoints
	if (iOrientation==EHorizontal)
		{
		if (rect.iTl.iX==iShaftStart)
			{
			gc.DrawLine(rect.iTl, TPoint(rect.iTl.iX, rect.iBr.iY));
			rect.iTl.iX++;
			}
		if (rect.iBr.iX==iShaftEnd)
			{
			gc.DrawLine(TPoint(rect.iBr.iX-1, rect.iTl.iY), TPoint(rect.iBr.iX-1, rect.iBr.iY));
			rect.iBr.iX--;
			}
		}
	else
		{
		if (rect.iTl.iY==iShaftStart)
			{
			gc.DrawLine(rect.iTl, TPoint(rect.iBr.iX, rect.iTl.iY));
			rect.iTl.iY++;
			}
		if (rect.iBr.iY==iShaftEnd)
			{
			gc.DrawLine(TPoint(rect.iTl.iX, rect.iBr.iY-1), TPoint(rect.iBr.iX, rect.iBr.iY-1));
			rect.iBr.iY--;
			}
		}
	gc.SetBrushColor(shaftColor);
	gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
	gc.Clear(rect );
	}

void CEikScrollBar::NewThumbAtPixelL()
// Move thumb to pixel position aPos,clearing the shafts,since the thumb has been resized.
	{
	UpdateThumbL();
    DrawThumbInShaftNow();
	}

void CEikScrollBar::UpdateThumbL()
	//
	// Sets the size and position of iThumb prior to a move/resize
	//
	{
	if (iThumb==NULL)
		return;
    TRect rect=Rect();
	rect.Shrink(KEikScrollBarBorderWidth,KEikScrollBarBorderWidth);
   	if (iOrientation==EHorizontal)
        {
        rect.iTl.iX=iThumbPos;
        rect.iBr.iX=iThumbPos+iThumbLength;
       }
    else
        {
        rect.iTl.iY=iThumbPos;
        rect.iBr.iY=iThumbPos+iThumbLength;
       }
	iThumb->SetExtentL(rect.iTl,rect.Size());
	}

void CEikScrollBar::UpdateButtonsL()
// Sets buttons position prior to a resize
	{
	if (!(iScrollBarDisplayFlags&EEikScrollBarNoNudgeButtons))
		{
		SetButtonPositionL(iButtons.iDecreaseNudge);
		SetButtonPositionL(iButtons.iIncreaseNudge);
		}
	if (iScrollBarDisplayFlags&EEikScrollBarHasPageButtons)
		{
		SetButtonPositionL(iButtons.iDecreasePage);
		SetButtonPositionL(iButtons.iIncreasePage);
		}
	if (iScrollBarDisplayFlags&EEikScrollBarHasHomeEndButtons)
		{
		SetButtonPositionL(iButtons.iHome);
		SetButtonPositionL(iButtons.iEnd);
		}
	}

void CEikScrollBar::SetButtonPositionL(CEikScrollButton* aButton)
// Calculates and sets a buttons position,making necessary adjustments for densely packed buttons
	{
	TInt scrollbarBreadth=ScrollBarBreadth();
	TSize size(scrollbarBreadth,scrollbarBreadth);	// !! for now
	TPoint position(0,0);
	TInt& pos=(iOrientation==EHorizontal ? position.iX : position.iY);
	switch (aButton->Type())
		{
    default:
        break;
	case CEikScrollButton::ENudgeLeft:
	case CEikScrollButton::ENudgeUp:
		pos=iDecreaseButtonsStart;
		if (iScrollBarDisplayFlags&EEikScrollBarHasPageButtons)
			pos+=scrollbarBreadth;
		if (iScrollBarDisplayFlags&EEikScrollBarHasHomeEndButtons)
			pos+=scrollbarBreadth;
		break;
	case CEikScrollButton::EPageLeft:
	case CEikScrollButton::EPageUp:
		pos=iDecreaseButtonsStart;
		if (iScrollBarDisplayFlags&EEikScrollBarHasHomeEndButtons)
			pos+=scrollbarBreadth;
		break;
	case CEikScrollButton::EHome:
	case CEikScrollButton::ETop:
		pos=iDecreaseButtonsStart;
		break;
	case CEikScrollButton::ENudgeRight:
	case CEikScrollButton::ENudgeDown:
		pos=iIncreaseButtonsStart;
		break;
	case CEikScrollButton::EPageRight:
	case CEikScrollButton::EPageDown:
		pos=iIncreaseButtonsStart;
		if (!(iScrollBarDisplayFlags&EEikScrollBarNoNudgeButtons))
			pos+=scrollbarBreadth;
		break;
	case CEikScrollButton::EEnd:
	case CEikScrollButton::EBottom:
		pos=iIncreaseButtonsStart;
		if (!(iScrollBarDisplayFlags&EEikScrollBarNoNudgeButtons))
			pos+=scrollbarBreadth;
		if (iScrollBarDisplayFlags&EEikScrollBarHasPageButtons)
			pos+=scrollbarBreadth;
		break;
		}
	aButton->SetExtentL(position,size); 
	SetButtonAdjacency(aButton);
	}

void CEikScrollBar::SetButtonAdjacency(CEikScrollButton* aButton)
// Set the buttons adjacency according to the layout
	{
	TCoeAdjacent adjBefore=(iOrientation==EHorizontal)? ECoeAdjLeft : ECoeAdjTop;
	TInt adjacent=adjBefore;
	TBool homeEndButtonsPresent=(iScrollBarDisplayFlags&EEikScrollBarHasHomeEndButtons);
	TBool pageButtonsPresent=(iScrollBarDisplayFlags&EEikScrollBarHasPageButtons);
	TPointerDownOn type=GeneralizeButtonType(aButton->Type());
	switch (type)
		{
    default:
        break;
	case EDecreaseNudgeButton:
	case EDecreasePageButton:
	case EHomeButton:
		if ((iScrollBarFlags&KButtonPositionMask)==EButtonsAtEndOfShaft)	  
			break;
		if ((type==EDecreasePageButton && !homeEndButtonsPresent) \
			|| (type==EDecreaseNudgeButton && !(homeEndButtonsPresent||pageButtonsPresent)))
			adjacent&=(~adjBefore);

		break;
		}
	aButton->SetAdjacent(adjacent);
	}

void CEikScrollBar::DoSetLengthL(TInt aLength)
// Changes the length and re-calculates required components and their layout.
    {
    iLength=aLength;
	TInt scrollbarBreadth=EScrollbarWidth;
    TSize size(scrollbarBreadth,aLength);
    if (iOrientation==EHorizontal)
        size.SetSize(aLength,scrollbarBreadth);
    SetSizeL(size);
	SetLayoutL();
   }

void CEikScrollBar::DoSetModel(const TEikScrollBarModel* aModel)
// Just change the internal model checking it's valid
	{
    iModel=(*aModel);
	CheckModelBounds();
	}

void CEikScrollBar::SetLayoutL()
// Sets the position of various components according to the flags
	{
	const TInt buttonSide=ScrollBarBreadth(); 
	// Recalculate the display flags
	CalcDisplayFlags();
	// First find out how many buttons we have
	TInt numberOfButtonPairs=NumberOfButtonPairs(ETrue);	// use the display flags to count

	// Now Work out where buttons are placed
	iDecreaseButtonsStart=0;
	if ((iScrollBarFlags&KButtonPositionMask)==EButtonsAtEndOfShaft)
		iDecreaseButtonsStart=iLength-((numberOfButtonPairs*buttonSide)<<1);
	iDecreaseButtonsEnd=iDecreaseButtonsStart+numberOfButtonPairs*buttonSide;
	
	iIncreaseButtonsStart=iLength-numberOfButtonPairs*buttonSide;
	if ((iScrollBarFlags&KButtonPositionMask)==EButtonsAtStartOfShaft)
		iIncreaseButtonsStart=numberOfButtonPairs*buttonSide;
	iIncreaseButtonsEnd=iIncreaseButtonsStart+numberOfButtonPairs*buttonSide;

	// Finally work out where the shaft is in relation to the buttons
	switch (iScrollBarFlags&KButtonPositionMask)
		{
	case EButtonsAtStartOfShaft:
		iShaftStart=iIncreaseButtonsEnd;//+KEikScrollBarBorderWidth;
		iShaftEnd=iLength;//-KEikScrollBarBorderWidth;
		break;
	case EButtonsAtEndOfShaft:
		iShaftStart=0;//KEikScrollBarBorderWidth;
		iShaftEnd=iDecreaseButtonsStart;//-KEikScrollBarBorderWidth;
		break;
	case EButtonsEitherSideOfShaft:
		iShaftStart=iDecreaseButtonsEnd;//+KEikScrollBarBorderWidth;
		iShaftEnd=iIncreaseButtonsStart;//-KEikScrollBarBorderWidth;
		}
	// May have more components than we started with
	CreateRequiredComponentsL(); 
	}

TInt CEikScrollBar::CalcThumbPixelPos() const
// Calculate thumb pos within the scroll bar's local pixel coordinate system.
	{
	TInt ret=iShaftStart;
	TInt scrollRange=iModel.iScrollSpan-iModel.iThumbSpan;
    if (scrollRange<=0)
		return ret;
    TInt maxRet=iShaftEnd-iThumbLength;
	if (scrollRange>0)
		ret+=iModel.iThumbPosition*(maxRet-iShaftStart)/scrollRange;
	if (ret>maxRet)
		ret=maxRet;
	return ret;
	}

TInt CEikScrollBar::CalcThumbModelPos() const
// Calculate model thumb pos from pixel pos
	{
	TInt ret=0;
	TInt scrollRange=iShaftEnd-iShaftStart-iThumbLength;
	if (scrollRange<=0)
		return ret;
	TInt maxRet=iModel.iScrollSpan-iModel.iThumbSpan;
	ret=(((iThumbPos-iShaftStart)<<1)*maxRet+scrollRange)/(scrollRange<<1);
	if (ret>maxRet)
		ret=maxRet;
	return ret;
	}

TInt CEikScrollBar::MinReqLengthToDisplay() const
// Returns the minimum length required to display all requested components
	{
	TInt minReqLengthToDisplay=0;
	const TInt buttonSide2=(ScrollBarBreadth()<<1);
	if (!(iScrollBarFlags&EEikScrollBarNoShaftOrThumb))
		{
		minReqLengthToDisplay+=(KEikScrollBarBorderWidth<<1);
		if (!(iScrollBarFlags&EEikScrollBarShaftButNoThumb))
			minReqLengthToDisplay+=EMinThumbLength;
		}
	if (!(iScrollBarFlags&EEikScrollBarNoNudgeButtons))
		minReqLengthToDisplay+=buttonSide2;
	if (iScrollBarFlags&EEikScrollBarHasPageButtons)
		minReqLengthToDisplay+=buttonSide2;
	if (iScrollBarFlags&EEikScrollBarHasHomeEndButtons)
		minReqLengthToDisplay+=buttonSide2;
	return minReqLengthToDisplay;
	}

void CEikScrollBar::CalcDisplayFlags()
// alters the display flags from the original flags to resolve layout issues
// if there isn't enough room to display all required components
	{
	iScrollBarFlags&=(~ENoComponentsToDisplay);
	iScrollBarDisplayFlags=(iScrollBarFlags&KDisplayComponentsMask);
	TInt scrollbarBreadth=ScrollBarBreadth();
	TInt overflow=MinReqLengthToDisplay()-iLength;
	while (overflow>0)
		{
		// first to die is the thumb!
		if (!(iScrollBarDisplayFlags&(EEikScrollBarNoShaftOrThumb|EEikScrollBarShaftButNoThumb)))
			{
			// has a thumb (and hence a shaft)
			iScrollBarDisplayFlags|=EEikScrollBarShaftButNoThumb;	// remove the thumb
			// don't destroy it since position needs to kept updated.
			overflow-=EMinThumbLength;
			continue;
			}
		// next reduce any shaft space to zero if neccesary
		if (!(iScrollBarDisplayFlags&EEikScrollBarNoShaftOrThumb))
			{
			iScrollBarDisplayFlags|=EEikScrollBarNoShaftOrThumb;	// remove the shaft
			overflow-=(KEikScrollBarBorderWidth<<1);
			continue;
			}
		// next are Home/End buttons
		if (iScrollBarDisplayFlags&EEikScrollBarHasHomeEndButtons)
			{
			iScrollBarDisplayFlags&=(~EEikScrollBarHasHomeEndButtons);
			DestroyButton(iButtons.iHome);
			DestroyButton(iButtons.iEnd);
			overflow-=(scrollbarBreadth<<1);
			continue;
			}
		// next are paging buttons
		if (iScrollBarDisplayFlags&EEikScrollBarHasPageButtons)
			{
			iScrollBarDisplayFlags&=(~EEikScrollBarHasPageButtons);
			DestroyButton(iButtons.iDecreasePage);
			DestroyButton(iButtons.iIncreasePage);
			overflow-=(scrollbarBreadth<<1);
			continue;
			}
		// next are nudge buttons
		if (!(iScrollBarDisplayFlags&EEikScrollBarNoNudgeButtons))
			{
			iScrollBarDisplayFlags|=EEikScrollBarNoNudgeButtons;
			DestroyButton(iButtons.iDecreaseNudge);
			DestroyButton(iButtons.iIncreaseNudge);
			overflow-=(scrollbarBreadth<<1);
			continue;
			}
		// left with no components?
		break;
		}
	if ((overflow<0)&&(iScrollBarDisplayFlags!=(iScrollBarFlags&KDisplayComponentsMask)))
		// Removing buttons may lead to excess space where we could put the shaft
		AddShaftIfPossible(Abs(overflow));
	if ((iScrollBarDisplayFlags==(EEikScrollBarNoNudgeButtons|EEikScrollBarNoShaftOrThumb|EEikScrollBarShaftButNoThumb))||
	    (iScrollBarDisplayFlags==(EEikScrollBarNoNudgeButtons|EEikScrollBarNoShaftOrThumb)))
		iScrollBarFlags|=ENoComponentsToDisplay;	// no visible components
	}

void CEikScrollBar::AddShaftIfPossible(TInt aExcessSpace)
// called at the end of CalcDisplayFlags().  Fills any excess space after removing buttons 
// with the shaft if required
	{
	__ASSERT_DEBUG(aExcessSpace>0,User::Panic(_L("ScrollBarExcessSpaceNotPositive"),0));
	if ((iScrollBarFlags&EEikScrollBarNoShaftOrThumb)||(aExcessSpace<(KEikScrollBarBorderWidth<<1)))
		return; // don't want it anyway or not enough space :(
	iScrollBarDisplayFlags&=(~EEikScrollBarNoShaftOrThumb);
	if (iScrollBarFlags&EEikScrollBarShaftButNoThumb)
		// Shaft only originally requested
		iScrollBarDisplayFlags|=EEikScrollBarShaftButNoThumb;
	else
		{
		// Shaft and thumb originally requested
		if (aExcessSpace>(KEikScrollBarBorderWidth<<1)+EMinThumbLength)
			iScrollBarDisplayFlags&=(~EEikScrollBarShaftButNoThumb); // room for the thumb
		else
			iScrollBarDisplayFlags|=EEikScrollBarShaftButNoThumb;	// no room for thumb
		}
	}

void CEikScrollBar::CheckModelBounds()
// Check the model is valid
	{
	iModel.CheckBounds();
	}

TInt CEikScrollBar::NumberOfButtonPairs(TBool aUseDisplayFlags)	const
// Returns the number of PAIRS of buttons requested/displayed depending on aUseDisplayFlags
// (aUseDisplayFlags==ETrue => number of button pairs displayed)
	{
	TInt flags=iScrollBarFlags;
	if (aUseDisplayFlags)
		flags=iScrollBarDisplayFlags;
	TInt numberOfButtonPairs=1;
	if (flags&EEikScrollBarNoNudgeButtons)
		numberOfButtonPairs--;
	if (flags&EEikScrollBarHasPageButtons)
		numberOfButtonPairs++;
	if (flags&EEikScrollBarHasHomeEndButtons)
		numberOfButtonPairs++;
	return numberOfButtonPairs;
	}

void CEikScrollBar::GetShaftRect(TRect& aRect) const
// Converts aRect from the whole scrollbar into just the shaft
	{
	aRect=Rect();
	switch (iOrientation)
		{
	case EHorizontal:
		aRect.iTl.iX=iShaftStart;//-KEikScrollBarBorderWidth;
		aRect.iBr.iX=iShaftEnd;//+KEikScrollBarBorderWidth;
		break;
	case EVertical:
		aRect.iTl.iY=iShaftStart;//-KEikScrollBarBorderWidth;
		aRect.iBr.iY=iShaftEnd;//+KEikScrollBarBorderWidth;
		break;
		}
	}

void CEikScrollBar::CheckAutoButtonDimming(TDrawNow aDrawNow/*=EDrawNow*/) 
// Dim out the appropriate buttons where neccessary
	{
	if (iScrollBarFlags&ENoAutoDimming)
		return;
	TInt increaseWereDimmed=(iScrollBarFlags&EIncreaseButtonsDimmed);
	TInt decreaseWereDimmed=(iScrollBarFlags&EDecreaseButtonsDimmed);
	if (iModel.iScrollSpan<=iModel.iThumbSpan)
		SetAllButtonsDimmed(ETrue);
	else if (iModel.iThumbPosition<=0)
		{
		SetDecreaseButtonsDimmed(ETrue);
		SetIncreaseButtonsDimmed(EFalse);
		}
	else if (iModel.iThumbPosition>=iModel.iScrollSpan-iModel.iThumbSpan) 
		{
		SetIncreaseButtonsDimmed(ETrue);
		SetDecreaseButtonsDimmed(EFalse);
		}
	else 
		SetAllButtonsDimmed(EFalse);
	if (aDrawNow==ENoDrawNow)
		return;
	if ((iScrollBarFlags&EIncreaseButtonsDimmed)!=increaseWereDimmed)
		DrawButtonsNow(EIncreaseOnly);
	if ((iScrollBarFlags&EDecreaseButtonsDimmed)!=decreaseWereDimmed)
		DrawButtonsNow(EDecreaseOnly);
	}

CEikScrollBar::TPointerDownOn CEikScrollBar::ResolveButtonPress(TInt aPos)
// Returns the button containing aPos
	{
	for (CEikScrollButton** button=&iButtons.iHome;button<=&iButtons.iEnd;++button)
		{
		if (!(*button))
			continue;
		TRect rect=(*button)->Rect();
		TInt buttonStart=(iOrientation==EHorizontal ? rect.iTl.iX : rect.iTl.iY);
		TInt buttonEnd=(iOrientation==EHorizontal ? rect.iBr.iX : rect.iBr.iY);
		if (aPos>=buttonStart && aPos<=buttonEnd)
			return GeneralizeButtonType((*button)->Type());
		}
	return ENone;
	}

CEikScrollBar::TPointerDownOn CEikScrollBar::GeneralizeButtonType(CEikScrollButton::TType aType) const
// simple code saving routine to convert between the two types
	{
	TPointerDownOn ret=EDecreaseNudgeButton;
	switch (aType)
		{
	case CEikScrollButton::ENudgeRight:
	case CEikScrollButton::ENudgeDown:
		ret=EIncreaseNudgeButton;
		break;
	case CEikScrollButton::EPageLeft:
	case CEikScrollButton::EPageUp:
		ret=EDecreasePageButton;
		break;
	case CEikScrollButton::EPageRight:
	case CEikScrollButton::EPageDown:
		ret=EIncreasePageButton;
		break;
	case CEikScrollButton::EHome:
	case CEikScrollButton::ETop:
		ret=EHomeButton;
		break;
	case CEikScrollButton::EEnd:
	case CEikScrollButton::EBottom:
		ret=EEndButton;
		break;
    default:
        break;
		}
	return ret;
	}

void CEikScrollBar::ReportScrollEventL(TEikScrollEvent aEvent)
// Report a scroll event to the observer after any pointer interaction
	{
	if (iScrollBarObserver)
		iScrollBarObserver->HandleScrollEventL(this,aEvent);
	}

// Reserved from CCoeControl

EXPORT_C void CEikScrollBar::Reserved_1()
	{
	}

EXPORT_C void CEikScrollBar::Reserved_2()
	{
	}



