Building custom widgets with the Zinzala SDK - page 8
We already saw the method cSkin::GetResourceL() earlier, so here's CreateBitmapFromResourceL():
cBitmap *CreateBitmapFromResourceL(const tBitmapResource &aRes,tBool aTransparent = true)
{
tErr lErr;
cBitmap *lBitmap = NULL;
lBitmap = new cBitmap(aRes.iWidth,aRes.iHeight,eSpaceColor8Bit,true,aRes.iColors);
lErr = cBitmap::VerifyD(lBitmap);
if(!lErr)
{
lBitmap->SetPalette(aRes.iPalette);
lBitmap->SetBits(aRes.iBits,aRes.iLength,0);
if(aTransparent)
lBitmap->MakeTransparent(aRes.iIndex);
return lBitmap;
}
else
throw uException(lErr,"CreateBitmapFromResourceL()");
}
Its implementation is quite straightforward. A bitmap is created with the size and number of colors required. Then we use VerifyD() to test the validity of the bitmap. If the bitmap is valid, we will set the palette of colors and copy its pixel data. If invalid, the object will be deleted by VerifyD(). Now, if the bitmap shall be transparent, we will apply the transparency. If the bitmap cannot be created successfully, due to a lack of memory or some other reason, the method will throw an exception.
In the class destructor, we need to delete all the memory that was allocated (if any). Here is the implementation:
cDConsoleView::~cDConsoleView()
{
if(iButtons)
delete [] iButtons;
if(iBackground)
delete iBackground;
if(iBStates)
{
for(tUint8 i=0;i<kStatesCount;i++)
if(iBStates[i] && i!=kStateActive) // Active and Normal states share the same bitmap
delete iBStates[i];
delete [] iBStates;
}
if(iBLabelsN)
{
for(tUint8 i=0;i<kLabelsCount;i++)
if(iBLabelsN[i])
delete iBLabelsN[i];
delete [] iBLabelsN;
}
if(iBLabelsD)
{
for(tUint8 i=0;i<kLabelsCount;i++)
if(iBLabelsD[i])
delete iBLabelsD[i];
delete [] iBLabelsD;
}
}
Drawing
The method Render() is responsible for drawing the console on the widget. Because the widget is using an offscreen bitmap, we do not have to worry about redrawing any part of the widget that is damaged. This is handled by the cDrawView.
The methods StartDrawing() and EndDrawing() from the class cDrawView are required before and after every block that perform some drawing:
void cDConsoleView::Render(tUint8 aButton,tBool aBackground)
{
StartDrawing();
if(aButton < kButtonsCount)
{
We will be using this method to render either the whole console or just a given button. When aButton equal kButtonsCount the whole console will be redrawn.
// Render only one button
DrawBitmap(iBStates[iButtons[aButton].iState],iButtons[aButton].iBFrame.GetLeftTop());
if(iButtons[aButton].iState == kStateDimmed)
DrawBitmap(iBLabelsD[iButtons[aButton].iLabel],iButtons[aButton].iLFrame.GetLeftTop());
else
DrawBitmap(iBLabelsN[iButtons[aButton].iLabel],iButtons[aButton].iLFrame.GetLeftTop());
The method cDrawView::DrawBitmap() draws a bitmap at a given location. We use it here to render the button using the bitmap associated with the button's state, followed by the label of the button.
}
else
{
// Render the background
if(aBackground)
DrawBitmap(iBackground);
// Render all the button
for(tUint8 i=0;i<kButtonsCount;i++)
{
DrawBitmap(iBStates[iButtons[i].iState],iButtons[i].iBFrame.GetLeftTop());
if(iButtons[i].iState == kStateDimmed)
DrawBitmap(iBLabelsD[iButtons[i].iLabel],iButtons[i].iLFrame.GetLeftTop());
else
DrawBitmap(iBLabelsN[iButtons[i].iLabel],iButtons[i].iLFrame.GetLeftTop());
}
When rendering the whole console, we first draw the background bitmap if required, then the 4 buttons with their labels.
}
EndDrawing();
}
In order to render the console for the first time, we implement the method OnScreen(). This method is executed when the widget is put onscreen, following the creation of the parent window:
void cDConsoleView::OnScreen()
{
cDrawView::OnScreen();
// Render the whole console (for the first time)
Render(kButtonsCount,true);
}
User's inputs
Although the user may think that our console contains 4 independent button widgets, it is in fact only one widget. Handling the user actions is going to require the need to know which one of the buttons was acted upon.
When given a position within the widget, the method FindButton() will give us the related button:
tUint8 cDConsoleView::FindButton(uPoint aPoint) const
{
tUint8 lButton;
for(lButton=0;lButton<kButtonsCount;lButton++)
{
if(iButtons[lButton].iBFrame.Contains(aPoint))
break;
}
return lButton;
}
Previous | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | Next
Print version