Constructing a Symbian container control
| Line 218: | Line 218: | ||
* [[Custom_control_-_focusing]] How to handle key events and change active custom control focus | * [[Custom_control_-_focusing]] How to handle key events and change active custom control focus | ||
* [[Custom_control_-_scrollbars]] How to add scroll bar into custom control | * [[Custom_control_-_scrollbars]] How to add scroll bar into custom control | ||
| + | * [[Custom_control_-_in_dialog]] How to add custom control into CAknDialog | ||
* [[Image:CustomControl.zip]] Example code patch | * [[Image:CustomControl.zip]] Example code patch | ||
[[Category:Symbian C++]][[Category:UI]][[Category:S60]][[Category:Code Examples]] | [[Category:Symbian C++]][[Category:UI]][[Category:S60]][[Category:Code Examples]] | ||
Revision as of 11:09, 19 March 2008
| ID | Creation date | March 7, 2008 | |
| Platform | S60 3rd Edition | 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 container control that owns custom controls. Example shows how to focus the first component with rectangle. Later we show how to change focus.
Example extends the existing code snippet Custom_control.
Container controls stores its 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 throught all components of this container controls
CCoeControlArray::TCursor cursor = Components().Begin();
CCoeControl* ctrl = NULL;
while ((ctrl = cursor.Control<CCoeControl>()) != NULL)
{
// If control is not visible 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 controls position
UpdateControls();
}
SizeChanged
When CMyContainerControl size changes (when e.g. SetRect() is called) have to components positions calculated again.
void CMyContainerControl::SizeChanged()
{
// Sets new position of the components
UpdateControls();
}
Focusing component
Folowing changes to CMyControl component.
- CMyControl::Draw() must call DrawFocusFrame() for drawing focus rectangle
- CMyControl::DrawFocusFrame() is new method where focus rectangle is drawed
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:
- Custom_control How to define custom control
- Custom_control_-_Construct_from_resource How to create control from resource
- Custom_control_-_container_control How to create container control
- Custom_control_-_focusing How to handle key events and change active custom control focus
- Custom_control_-_scrollbars How to add scroll bar into custom control
- Custom_control_-_in_dialog How to add custom control into CAknDialog
- File:CustomControl.zip Example code patch

