×
Namespaces

Variants
Actions
(Difference between revisions)

Constructing a Symbian container control

From Nokia Developer Wiki
Jump to: navigation, search
Forum Nokia KB (Talk | contribs)
seppo_fn (Talk | contribs)

Revision as of 13:23, 28 March 2008


Template:KBCS

ID CS000861 Creation date March 25, 2008
Platform S60 3rd Edition, FP1 Tested on devices Nokia N95
Category Symbian C++ Subcategory UI


Keywords (APIs, classes, methods, functions): CCoeControl, TResourceReader, CCoeControlArray

Overview

This code snippet shows how to create a container control that owns custom controls. The example shows how to focus the first component with a rectangle and how to change focus.

The example extends the existing code snippet CS000859 - Custom control.

Container controls store their controls into CCoeControlArray.

Header

class CMyContainerControl : public CCoeControl
{
public:
static CMyContainerControl* NewL(const TRect& aRect);
static CMyContainerControl* NewLC(const TRect& aRect);
virtual ~CMyContainerControl();
 
private: // from CCoeControl
void Draw(const TRect& aRect) const;
void SizeChanged();
 
public: // own methods
// NOTE: Transfer ownership to CMyContainerControl
void AddControlL(CCoeControl* aControl,TInt aControlId);
void UpdateControls();
 
private: // own methods
CMyContainerControl();
void ConstructL(const TRect& aRect);
};


Source

CMyContainerControl* CMyContainerControl::NewL(const TRect& aRect)
{
CMyContainerControl* self = CMyContainerControl::NewLC(aRect);
CleanupStack::Pop(self);
return self;
}
 
CMyContainerControl* CMyContainerControl::NewLC(const TRect& aRect)
{
CMyContainerControl* self = new(ELeave) CMyContainerControl();
CleanupStack::PushL(self);
self->ConstructL(aRect);
return self;
}
 
CMyContainerControl::CMyContainerControl()
{
}
 
CMyContainerControl::~CMyContainerControl()
{
}
 
void CMyContainerControl::ConstructL(const TRect& aRect)
{
// No parent owner, so create an own window
CreateWindowL();
 
// Initialize component array
InitComponentArrayL();
 
SetRect(aRect);
 
ActivateL();
}
 
void CMyContainerControl::SizeChanged()
{
UpdateControls();
}
 
void CMyContainerControl::UpdateControls()
{
TPoint position;
 
// Goes through all components of this container control
CCoeControlArray::TCursor cursor = Components().Begin();
CCoeControl* ctrl = NULL;
while ((ctrl = cursor.Control<CCoeControl>()) != NULL)
{
// If control is not visible, it does not handle it
if (!ctrl->IsVisible())
{
cursor.Next();
continue;
}
 
// Set position
ctrl->SetPosition(position);
 
// Set size
TSize size = ctrl->MinimumSize();
size.SetSize(Rect().Width(),size.iHeight);
ctrl->SetSize(size);
 
// Visible?
if (position.iY >= Rect().iBr.iY)
{
ctrl->MakeVisible(EFalse);
}
else
{
ctrl->MakeVisible(ETrue);
}
 
// Store position of last component
position.iY += size.iHeight;
 
cursor.Next();
}
}
 
void CMyContainerControl::Draw(const TRect& /*aRect*/) const
{
CWindowGc& gc = SystemGc();
gc.SetBrushColor(KRgbBlack);
gc.Clear(Rect());
}
 
void CMyContainerControl::AddControlL(CCoeControl* aControl,TInt aControlId)
{
// NOTE: Transfer ownership of CCoeControl to CMyContainerControl
// Add control into container control
Components().AppendLC(aControl,aControlId);
CleanupStack::Pop(aControl);
 
// Focus first component
if (Components().Count()==1)
{
aControl->SetFocus(ETrue);
}
 
// Update control's position
UpdateControls();
}

SizeChanged

When CMyContainerControl's size changes (when, for example, SetRect() is called), components' positions have to be calculated again.

void CMyContainerControl::SizeChanged()
{
// Sets new position of the components
UpdateControls();
}

Focusing component

Make the following changes to the CMyControl component.

  • CMyControl::Draw() must call DrawFocusFrame() for drawing the focus rectangle
  • CMyControl::DrawFocusFrame() is a new method where focus rectangle is drawn
void CMyControl::Draw(const TRect& aRect) const
{
CWindowGc& gc = SystemGc();
gc.SetBrushColor(KRgbBlue);
gc.Clear(Rect());
 
DrawFocusFrame(aRect);
}
 
void CMyControl::DrawFocusFrame(const TRect& aRect) const
{
// Nothing to draw if not focused
if ( IsFocused() == EFalse )
return;
 
// Prep for draw
CWindowGc& gc = SystemGc();
gc.SetPenStyle( CGraphicsContext::ESolidPen );
gc.SetPenSize( TSize(KFocusFrameWidth,KFocusFrameWidth) );
gc.SetBrushStyle( CGraphicsContext::ENullBrush );
gc.SetPenColor( KRgbDarkGray );
 
// Draw the rounded rectangle
gc.DrawRoundRect( aRect, TSize( KFrameRoundRadius, KFrameRoundRadius ) );
}

Postconditions

CMyContainerControl container has some CMyControlcustom controls in a list.

See also

Custom Control Series:

116 page views in the last 30 days.
×