// EIKBTPAN.CPP
//
// Copyright (c) 1997-1999 Symbian Ltd.  All rights reserved.
//
 
#include <eikbtpan.h>
#include <eiklbbut.h>
#include <eikcmbut.h>
#include <eiklabel.h>
#include <barsread.h>
#include <coedef.h>
#include <eikenv.h>
#include <eiklabel.h>
#include <eikdialg.hrh>
#include <eikon.rsg>

const TInt KButtonArrayGranularity=2;
const TInt KPanelHMargin=4;
const TInt KPanelTopMargin=6;
const TInt KPanelBottomMargin=2;
const TInt KHorizontalGapBetweenButtons=16;
//const TInt KVerticalGapBetweenButtons=11; // too big ???
const TInt KVerticalGapBetweenButtons=5;
const TInt KVerticalSpaceForNonLabeledButtons=6;
//const TInt KVerticalGapBetweenButtons=3;
const TInt KEikButtonLabelTopMargin=2;
const TInt KEikButtonLabelBottomMargin=1;
const TInt KStdMinButtonWidth=50;

#define VERTICAL_BUTTONS_AT_BOTTOM

EXPORT_C CEikButtonPanel::~CEikButtonPanel()
	{
	if (iButtonArray)
		{
		const TInt count=iButtonArray->Count();
		for (TInt ii=0;ii<count;++ii)
			{
			SEikPanelButton& button=(*iButtonArray)[ii];
			delete button.iButton;
			}
		delete iButtonArray;
		}
	}

EXPORT_C CEikButtonPanel::CEikButtonPanel()
	: iMinButWidth(KStdMinButtonWidth)
	{
	__DECLARE_NAME(_S("CEikButtonPanel"));
	SetNonFocusing();
	}

EXPORT_C void CEikButtonPanel::ConstructL()
	{
	iButtonArray=new(ELeave) CArrayFixFlat<SEikPanelButton>(KButtonArrayGranularity);
	}

EXPORT_C void CEikButtonPanel::SetHorizontal()
	{
	iHorizontal=ETrue;
	}

EXPORT_C TInt CEikButtonPanel::ButtonId(CCoeControl* aControl) const
	{
	const TInt count=iButtonArray->Count();
	for (TInt ii=0;ii<count;++ii)
		{
		SEikPanelButton& button=(*iButtonArray)[ii];
		if (button.iButton==aControl)
			return(button.iId);
		}
	return(0);
	}

EXPORT_C CEikCommandButtonBase* CEikButtonPanel::ButtonById(TInt aButtonId) const
	{
	CEikLabeledButton* button=LabeledButtonById(aButtonId);
	if (button)
		return button->Button();
	return NULL;
	}

EXPORT_C CEikLabeledButton* CEikButtonPanel::LabeledButtonById(TInt aButtonId) const
	{
	const TInt count=iButtonArray->Count();
	for (TInt ii=0;ii<count;++ii)
		{
		SEikPanelButton& button=(*iButtonArray)[ii];
		if (button.iId==aButtonId)
			return(button.iButton);
		}
	return(NULL);
	}

EXPORT_C void CEikButtonPanel::AddButtonL(CEikLabeledButton* aButton,TInt aId)
	{
	SEikPanelButton button;
	button.iButton=aButton;
	button.iId=aId;
	aButton->SetNonFocusing();
	aButton->SetContainerWindowL(*this);
	aButton->CopyControlContextFrom(this);
	aButton->SetObserver(Observer());
	iButtonArray->AppendL(button);
	ResetMinimumSize();
	}

EXPORT_C void CEikButtonPanel::ConstructFromResourceL(TResourceReader& aReader)
	{
	ConstructL();
	const TInt count=aReader.ReadInt16();
	for (TInt ii=0;ii<count;++ii)
		{
		const TInt id=aReader.ReadInt16();
		CEikLabeledButton* button=new(ELeave) CEikLabeledButton;
		CleanupStack::PushL(button);
		button->CopyControlContextFrom(this);
		button->ConstructFromResourceL(aReader);
		if (button->ShowsHotKey())
			{
			CEikLabel* label=button->Label();
			label->CopyControlContextFrom(this);
			label->iMargin.iTop=KEikButtonLabelTopMargin;
			label->iMargin.iBottom=KEikButtonLabelBottomMargin;
			}
		AddButtonL(button,id);
		CleanupStack::Pop();
		}
	}

EXPORT_C void CEikButtonPanel::ResetMinimumSize()
	{
	iMinSize=TSize(0,0);
	}

EXPORT_C void CEikButtonPanel::SetMinButtonWidth(TInt aWidth)
	{
	iMinButWidth=aWidth;
	}

EXPORT_C TInt CEikButtonPanel::CountComponentControls() const
	{
	return iButtonArray->Count();
	}

EXPORT_C CCoeControl* CEikButtonPanel::ComponentControl(TInt aIndex) const
	{
	return (*iButtonArray)[aIndex].iButton;
	}

EXPORT_C void CEikButtonPanel::SizeChangedL()
	{
	const TRect rect=Rect();
	TPoint tl=rect.iTl;
	TInt excess=iSize.iWidth-iMinSize.iWidth;
	if (excess>0)
		tl.iX+=excess/2;
#if defined(VERTICAL_BUTTONS_AT_BOTTOM)
	excess=iSize.iHeight-iMinSize.iHeight;
	if (excess)
		tl.iY+=(iHorizontal? excess/2: excess);
#endif
	tl.iX+=KPanelHMargin;
	tl.iY+=KPanelTopMargin;
	const TInt count=iButtonArray->Count();
	for (TInt ii=0;ii<count;++ii)
		{
		SEikPanelButton& button=(*iButtonArray)[ii];
		TInt butHeight=button.iButton->MinimumSize().iHeight;
		if (!button.iButton->ShowsHotKey())
			butHeight+=KVerticalSpaceForNonLabeledButtons;
		button.iButton->SetExtentL(tl,TSize(iButWidth,butHeight));
		if (iHorizontal)
			tl.iX+=iButWidth+KHorizontalGapBetweenButtons;
		else
			tl.iY+=butHeight+KVerticalGapBetweenButtons;
		}
	}

EXPORT_C TSize CEikButtonPanel::MinimumSize()
	{
	if (iMinSize.iWidth)
		return(iMinSize);
	iButWidth=iMinButWidth;
	const TInt count=iButtonArray->Count();
	for (TInt ii=0;ii<count;++ii)
		{
		SEikPanelButton& button=(*iButtonArray)[ii];
		TSize butSize=button.iButton->MinimumSize();
		if (!button.iButton->ShowsHotKey())
			butSize.iHeight+=KVerticalSpaceForNonLabeledButtons;
		if (iButWidth<butSize.iWidth)
			iButWidth=butSize.iWidth;
		if (iHorizontal)
			{
			if (iMinSize.iHeight<butSize.iHeight)
				iMinSize.iHeight=butSize.iHeight;
			}
		else
			iMinSize.iHeight+=butSize.iHeight;
		}
	if (iHorizontal)
		{
		iMinSize.iWidth=iButWidth*count;
		iMinSize.iWidth+=(count-1)*KHorizontalGapBetweenButtons;
		}
	else
		{
		iMinSize.iWidth=iButWidth;
		iMinSize.iHeight+=(count-1)*KVerticalGapBetweenButtons;
		}
	iMinSize.iWidth+=KPanelHMargin*2;
	iMinSize.iHeight+=KPanelTopMargin+KPanelBottomMargin;
	return iMinSize;
	}

EXPORT_C CEikCommandButtonBase* CEikButtonPanel::ButtonForKey(TInt aChar,TInt& aButtonId) const
	{
	const TCharF foldedChar(aChar);
	const TInt count=iButtonArray->Count();
	for (TInt ii=0;ii<count;++ii)
		{
		SEikPanelButton& item=(*iButtonArray)[ii];
		CEikLabeledButton* button=item.iButton;
		if (foldedChar==TCharF(button->HotKeyCode()))
			{
			aButtonId=item.iId;
			if (button->IsVisible())
				return button->Button();
			break;
			}
		}
	return(NULL);
	}

EXPORT_C void CEikButtonPanel::MakeButtonVisible(TInt aButtonId,TBool aVisible)
	{
	const TInt count=iButtonArray->Count();
	for (TInt ii=0;ii<count;++ii)
		{
		SEikPanelButton& button=(*iButtonArray)[ii];
		if (button.iId==aButtonId)
			{
			button.iButton->MakeVisible(aVisible);
			return;
			}
		}
	}

EXPORT_C void CEikButtonPanel::Reserved_1()
	{}
EXPORT_C void CEikButtonPanel::Reserved_2()
	{}
