This document shows you how to create an animation using the Bitmap Animation framework.
The Bitmap Animation
framework (bmpanim.dll
) uses the font and bitmap server
(fbscli.dll
) to provide the bitmap images (CFbsBitmap
s).
An
animation DLL (bmpansrv.dll
), loaded by the Window Server,
is used to perform the animation.
The animation DLL uses the bitgdi
component (bitgdi.dll
) to draw the bitmaps.
To use a bitmap animation in your application you need to:
define one or more animation frames, each of which owns a bitmap,
assign the frames to an animation container,
create an animation player object and pass the animation container to it. This communicates with the window server to start and stop playing the animation inside a window.
Collectively, these steps make up the Bitmap Animation framework. The key client side classes that are involved in these steps are:
The rest of this document describes each of these steps, starting with the animation frame.
The CBitmapFrameData
class
represents a single frame in an animation. The following properties of a frame
can be set:
the bitmap image,
the mask, which is used for making parts of the image transparent,
the time the frame is displayed, in milliseconds,
the position in the window where the frame is displayed.
These properties can either be set in CBitmapFrameData::NewL()
or
by calling various setter functions, described below.
Setting the image and mask bitmaps
The following code loads the bitmap and mask from a multi bitmap file, and constructs the frame, setting its bitmap and mask, which it takes ownership of:
CFbsBitmap* bitmap=new (ELeave) CFbsBitmap; // load the image bitmap from an mbm file CleanupStack::PushL(bitmap); User::LeaveIfError(bitmap->Load(KMBMFileName, EMbmAnimFrame1)); CFbsBitmap* mask=new (ELeave) CFbsBitmap; // load the mask from the same mbm file CleanupStack::PushL(mask); User::LeaveIfError(mask->Load(KMBMFileName, EMbmAnimFrameMask1)); CBitmapFrameData* frame1 = CBitmapFrameData::NewL(bitmap, mask); CleanupStack::Pop(2); // bitmap, mask
CBitmapFrameData::SetBitmap()
and CBitmapFrameData::SetMask()
could alternatively be used.
An animation can have multiple frames,
each of which has an image and mask bitmap. Each frame stores a flag to indicate
whether or not it owns the bitmaps. If the frame owns the bitmaps, they are
deleted in the frame’s destructor. This flag can be set or unset by calling CBitmapFrameData::SetBitmapsOwnedExternally()
.
By default, bitmaps are owned by the frame.
The mask is used in the standard way for a bitmap mask, so pixels in the bitmap image that map to black pixels in the mask are drawn, while pixels that map to white pixels in the mask are not, so appear transparent.
Setting the time interval
The time period for the frame to be displayed on the screen is set in milliseconds:
frame1->SetInterval(125);
Note
that a default time interval can be set in the frame container (described
in the next section) by calling CBitmapAnimClientData::SetFrameInterval()
.
Any value set in the container will apply to frames that have not set an interval
themselves.
Setting the frame’s position
The position
of the frame relative to the animation window is set using CBitmapFrameData::SetPosition()
:
TPoint framePos(3,6); frame1->SetPosition(framePos);
Note that the position can also
be specified in RBitmapAnim
; if so, this value applies
to all frames.
When you have finished defining the animation frame(s),
use the frame container class, CBitmapAnimClientData
, to
create the animation.
Frames are grouped into an
animation frame container (CBitmapAnimClientData
), which
allows the following behaviour to be set:
append frames to the container,
set a default display interval for all frames, (note that the time interval set by an individual frame takes precedence, for that frame, over the default interval),
set one of the following play modes for the animation: play once, loop or bounce (plays forwards and backwards),
set the animation to flash,
provide an additional bitmap frame to use for the background to the animation (explained below).
Appending frames
First, create the frame container, and append the frame(s) to it in the correct sequence:
CBitmapAnimClientData* animFrames=CBitmapAnimClientData::NewL(); CleanupStack::PushL(animFrames); animFrames->AppendFrameL(*frame1); animFrames->AppendFrameL(*frame2); // etc.
Setting the default display interval
A default display interval can be set for the animation:
animFrames->SetFrameInterval(100);
This
applies only to frames which have not specified their own interval (using CBitmapFrameData::SetInterval()
).
In this example, the default interval for frames without their own interval
is 100 milliseconds (0.1 second). It can be used to ensure that all frames
are displayed for the same length of time.
Setting the play mode
There are three play modes: play once, play repeatedly in the same direction ('loop') and play forwards and backwards repeatedly ('bounce'). This code sets the animation to play once:
animFrames->SetPlayMode(CBitmapAnimClientData::EPlay);
Other properties
CBitmapAnimClientData::SetFlash()
and CBitmapAnimClientData::SetBackgroundFrame()
are used to set/unset the flash flag and the background frame, respectively.
The flash flag determines whether the animation should flash or not.
The background frame, which is optional, is used to clear the current frame before drawing the next one. If no background frame is provided by the client, the window server creates its own background frame using the original screen contents, and updates it when the animation window is redrawn.
If the client-provided background frame contains an image bitmap and a mask, the background image used is a combination of the screen contents and the supplied background bitmap. If the client-provided background frame has a bitmap but no mask, the bitmap is used as the background.
When the animation is ready
to play, it must be packaged and sent to the window server’s animation DLL.
This is done through an animation player (RBitmapAnim
)
object.
RBitmapAnim
allows you to do the following:
specify the window in which the animation is displayed,
associate the animation
with an RAnimDll
object, which provides a connection to
the window server,
pass the animation object to the window server’s animation DLL,
specify the number of times the animation should play,
start and stop playing the animation. Optionally the animation can start playing from a particular frame.
Note that after the animation object has been set up and passed to
the window server, the general attributes of the animation, namely the flash
property, the default display time for each frame and the play mode can still
be changed, using the following RBitmapAnim
functions:
Any changes to these properties made using RBitmapAnim
will
override the values previously set in CBitmapAnimClientData
.
Constructing the animation player
RAnimDll
is a handle
to the server-side animation DLL. It is used to load the window server animation
DLL, bmpansrv.dll
, which provides the functions that
perform the frames animation. The RAnimDll
instance is passed
to the RBitmapAnim
constructor.
RAnimDll animDLL(iEikonEnv->WsSession()); // session is used to interact with the window server _LIT(KDllName, "BMPANSRV.DLL"); User::LeaveIfError(animDll.Load(KDllName)); RBitmapAnim animPlayer(animDLL); animPlayer.ConstructL(Window());
Passing the animation object to the window server
The animation frame container (CBitmapAnimClientData
)
should be passed via the RBitmapAnim
object to the window
server. This is done using the function SetBitmapAnimDataL()
.
Note that calling this function does not cause the animation to start playing:
animPlayer.SetBitmapAnimDataL(*animFrames);
Setting the number of cycles
If the animation should play more than once, the number of cycles should be set:
animPlayer.SetNumberOfCyclesL(10);
Note that if the animation's play mode is 'bounce', the number of cycles must be set to at least two to ensure a complete animation routine.
Setting the position
To set the animation’s position, use SetPositionL()
.
This value is an offset from the origin of the animation window.
TPoint animPos(20,40); animPlayer.SetPositionL(animPos);
Starting/stopping the animation
The RBitmapAnim::StartL()
and RBitmapAnim::StopL()
functions
send commands to the animation DLL to start/stop the animation routine.
Calling RBitmapAnim::DisplayFrameL()
before
the animation has started sets the frame from which the animation should start
playing.
Freeing resources
After they have been finished
with, Close()
should be called on the RAnimDll
and RBitmapAnim
objects.
animPlayer.Close(); animDLL.Close();