|
||
VectorSprite
: drawing sprites
Found in: examples\Graphics\WS\VectorSprite\
These are the main files contained in the examples. Some extra files may be needed to run the examples, and these will be found in the appropriate examples directory.
Note: This example is designed to work properly only with techview, there is no guarantee that it will work properly with other interfaces
// AppHolder.cpp
//
// Copyright (c) 2005 Symbian Softwares Ltd. All rights reserved.
//
#include "AppHolder.h"
#include "VectorSprite.h"
#include <EikStart.h>
//
// EXPORTed functions
//
EXPORT_C CApaApplication* NewApplication()
{
return new CAppholderApplication;
}
// The below section is added to make the code compatible with v9.1
// This is because only exe files are compatible with v9.1
#if (defined __WINS__ && !defined EKA2) // E32Dll used only when WINS defined and EKA2 not defined
GLDEF_C TInt E32Dll(enum TDllReason)
{
return KErrNone;
}
#else // else E32Main is used
GLDEF_C TInt E32Main()
{
return EikStart::RunApplication(NewApplication);
}
#endif
////////////////////////////////////////////////////////////////
//
// Application class, CAppholderApplication
//
////////////////////////////////////////////////////////////////
TUid CAppholderApplication::AppDllUid() const
{
return KUidAppholder;
}
CApaDocument* CAppholderApplication::CreateDocumentL()
{
// Construct the document using its NewL() function, rather
// than using new(ELeave), because it requires two-phase
// construction.
return new (ELeave) CAppholderDocument(*this);
}
////////////////////////////////////////////////////////////////
//
// Document class, CAppholderDocument
//
////////////////////////////////////////////////////////////////
// C++ constructor
CAppholderDocument::CAppholderDocument(CEikApplication& aApp)
: CEikDocument(aApp)
{
}
CEikAppUi* CAppholderDocument::CreateAppUiL()
{
return new(ELeave) CAppholderAppUi;
}
CAppholderDocument::~CAppholderDocument()
{
}
////////////////////////////////////////////////////////////////
//
// App UI class, CAppholderAppUi
//
////////////////////////////////////////////////////////////////
void CAppholderAppUi::ConstructL()
{
BaseConstructL();
iClient=CExampleWsClient::NewL(ClientRect());
}
CAppholderAppUi::~CAppholderAppUi()
{
delete iClient;
}
void CAppholderAppUi::HandleCommandL(TInt aCommand)
{
switch (aCommand)
{
case EEikCmdExit:
Exit();
break;
}
}
// Base.cpp
//
// Copyright (c) 2005 Symbian Softwares Ltd. All rights reserved.
//
#include <w32std.h>
#include "Base.h"
///////////////////////////////////////////////////////////////////////////////
// CWindow implementation
///////////////////////////////////////////////////////////////////////////////
CWindow::CWindow(CWsClient* aClient)
: iClient(aClient)
{
}
void CWindow::ConstructL (const TRect& aRect, const TRgb& aColor, CWindow* aParent)
{
_LIT(KFontName,"Swiss");
// If a parent window was specified, use it; if not, use the window group
// (aParent defaults to 0).
RWindowTreeNode* parent= aParent ? (RWindowTreeNode*) &(aParent->Window()) : &(iClient->iGroup);
// Allocate and construct the window
iWindow=RWindow(iClient->iWs);
User::LeaveIfError(iWindow.Construct(*parent,(TUint32)this));
// Store the window's extent
iRect = aRect;
// Set up the new window's extent
iWindow.SetExtent(iRect.iTl, iRect.Size());
// Set its background color
iWindow.SetBackgroundColor (aColor);
// Set up font for displaying text
TFontSpec fontSpec(KFontName,200);
User::LeaveIfError(iClient->iScreen->GetNearestFontInTwips(iFont,fontSpec));
// Activate the window
iWindow.Activate();
}
CWindow::~CWindow()
{
iWindow.Close();
iClient->iScreen->ReleaseFont(iFont);
}
RWindow& CWindow::Window()
{
return iWindow;
}
CWindowGc* CWindow::SystemGc()
{
return iClient->iGc;
}
CWsScreenDevice* CWindow::Screen()
{
return iClient->iScreen;
}
CFont* CWindow::Font()
{
return iFont;
}
///////////////////////////////////////////////////////////////////////////////
// CWsRedrawer implementation
///////////////////////////////////////////////////////////////////////////////
CWsRedrawer::CWsRedrawer()
: CActive(CActive::EPriorityLow)
{
}
void CWsRedrawer::ConstructL(CWsClient* aClient)
{
iClient=aClient; // remember WsClient that owns us
CActiveScheduler::Add(this); // add ourselves to the scheduler
IssueRequest(); // issue request to draw
}
CWsRedrawer::~CWsRedrawer()
{
Cancel();
}
void CWsRedrawer::IssueRequest()
{
iClient->iWs.RedrawReady(&iStatus);
SetActive();
}
void CWsRedrawer::DoCancel()
{
iClient->iWs.RedrawReadyCancel();
}
void CWsRedrawer::RunL()
{
// find out what needs to be done in response to the event
TWsRedrawEvent redrawEvent;
iClient->iWs.GetRedraw(redrawEvent); // get event
CWindow* window=(CWindow*)(redrawEvent.Handle()); // get window
if (window)
{
TRect rect=redrawEvent.Rect(); // and rectangle that needs redrawing
// now do drawing
iClient->iGc->Activate(window->Window());
window->Window().BeginRedraw();
window->Draw(rect);
window->Window().EndRedraw();
iClient->iGc->Deactivate();
}
// maintain outstanding request
IssueRequest();
}
/////////////////////////////////////////////////////////////////////////////////////
// CWsClient implementation
/////////////////////////////////////////////////////////////////////////////////////
CWsClient::CWsClient()
: CActive(CActive::EPriorityStandard)
{
}
void CWsClient::ConstructL()
{
// add ourselves to active scheduler
CActiveScheduler::Add(this);
// get a session going
User::LeaveIfError(iWs.Connect());
// construct our one and only window group
iGroup=RWindowGroup(iWs);
User::LeaveIfError(iGroup.Construct(2,ETrue)); // '2' is a meaningless handle
// construct screen device and graphics context
iScreen=new (ELeave) CWsScreenDevice(iWs); // make device for this session
User::LeaveIfError(iScreen->Construct()); // and complete its construction
User::LeaveIfError(iScreen->CreateContext(iGc)); // create graphics context
// construct redrawer
iRedrawer=new (ELeave) CWsRedrawer;
iRedrawer->ConstructL(this);
// construct main window
ConstructMainWindowL();
// request first event and start scheduler
IssueRequest();
}
CWsClient::~CWsClient()
{
// neutralize us as an active object
Deque(); // cancels and removes from scheduler
// get rid of everything we allocated
delete iGc;
delete iScreen;
delete iRedrawer;
// destroy window group
iGroup.Close(); // what's the difference between this and destroy?
// finish with window server
iWs.Close();
}
void CWsClient::IssueRequest()
{
iWs.EventReady(&iStatus); // request an event
SetActive(); // so we're now active
}
void CWsClient::DoCancel()
{
iWs.EventReadyCancel(); // cancel event request
}
void CWsClient::ConstructMainWindowL()
{
}
// VectorSprite.CPP
//
// Copyright (c) 2005 Symbian Softwares Ltd. All rights reserved.
//
#include <w32std.h>
#include "Base.h"
#include "VectorSprite.h"
CSprite::CSprite(CWsClient *aClient) : iClient(aClient)
{
}
CSprite::~CSprite()
{
for (TInt i=0; i<4; i++)
{
delete iSpriteMember[i].iBitmap;
delete iSpriteMember[i].iMaskBitmap;
}
iSprite.Close();
}
void CSprite::ConstructL(CWindow* aWindow)
{
iSprite = RWsSprite(iClient->iWs);
User::LeaveIfError(iSprite.Construct(aWindow->Window(), TPoint(100,100), 0));
for (TInt spriteNum = 0; spriteNum < 4; spriteNum++)
{
CreateBitmap(iSpriteMember[spriteNum].iBitmap, spriteNum, EFalse);
CreateBitmap(iSpriteMember[spriteNum].iMaskBitmap, spriteNum, ETrue);
iSpriteMember[spriteNum].iInvertMask = EFalse;
iSpriteMember[spriteNum].iOffset = TPoint (0,0);
iSpriteMember[spriteNum].iInterval = TTimeIntervalMicroSeconds32 (500000);
iSpriteMember[spriteNum].iDrawMode = CGraphicsContext::EDrawModePEN;
User::LeaveIfError(iSprite.AppendMember(iSpriteMember[spriteNum]));
}
User::LeaveIfError(iSprite.Activate());
iSprite.UpdateMember(3);
}
void CSprite::CreateBitmap(CFbsBitmap* &aBitmap, TInt aSpriteNum, TBool aDoMask)
{
// device and context for drawing to the off-screen bitmap
CFbsBitmapDevice* bitmapDevice;
CGraphicsContext* bitmapContext;
// create bitmap
// aBitmap is effectively member data of CSprite, and this function is only
// called from CSprite's constructor. This means we can be sure aBitmap has
// not been new'ed before (if it had, we'd need to do a delete here and set
// aBitmap to 0.
aBitmap = new (ELeave) CFbsBitmap();
aBitmap->Create(TSize(50,50),EGray4);
// create a device and gc for it
bitmapDevice = CFbsBitmapDevice::NewL(aBitmap);
bitmapDevice->CreateContext(bitmapContext);
// Set up pen color etc.
bitmapContext->SetBrushColor(aDoMask? TRgb::Gray4(0) : TRgb::Gray4(2));
bitmapContext->SetBrushStyle(CGraphicsContext::ESolidBrush);
bitmapContext->SetPenStyle(CGraphicsContext::ENullPen);
bitmapContext->DrawRect(TRect(TSize(50,50)));
bitmapContext->SetPenStyle(CGraphicsContext::ESolidPen);
bitmapContext->SetPenSize(TSize(4,4));
bitmapContext->SetPenColor(aDoMask? TRgb::Gray4(3) : TRgb::Gray4(0));
// draw to it
switch (aSpriteNum)
{
case 0:
bitmapContext->DrawLine (TPoint(10,10), TPoint(40,40));
break;
case 1:
bitmapContext->DrawLine (TPoint(25,10), TPoint(25,40));
break;
case 2:
bitmapContext->DrawLine (TPoint(40,10), TPoint(10,40));
break;
case 3:
bitmapContext->DrawLine (TPoint(10,25), TPoint(40,25));
break;
}
// delete the context and device
delete bitmapContext;
delete bitmapDevice;
}
/****************************************************************************\
| Function: Constructor/Destructor for CMainWindow
| Input: aClient Client application that owns the window
\****************************************************************************/
CMainWindow::CMainWindow (CWsClient* aClient)
: CWindow (aClient)
{
}
CMainWindow::~CMainWindow ()
{
iWindow.Close();
}
/****************************************************************************\
| Function: CMainWindow::Draw
| Purpose: Redraws the contents of CMainWindow within a given
| rectangle.
| Input: aRect Rectangle that needs redrawing
| Output: None
\****************************************************************************/
void CMainWindow::Draw(const TRect& aRect)
{
CWindowGc* gc=SystemGc(); // get a gc
gc->SetClippingRect(aRect); // clip outside this rect
gc->Clear(aRect); // clear
gc->SetPenStyle(CGraphicsContext::ESolidPen);
gc->SetPenColor(TRgb::Gray4(2));
TSize size = Window().Size();
TInt width = size.iWidth;
TInt height = size.iHeight;
TInt numHoriz=height/5;
TInt numVert=width/10;
for (TInt i=numHoriz; i>0; i--)
{
gc->DrawLine (TPoint(0,height/numHoriz*i), TPoint(width, height/numHoriz*i));
}
for (TInt j=numVert; j>0; j--)
{
gc->DrawLine (TPoint(width/numVert*j, 0), TPoint(width/numVert*j, height));
}
}
/****************************************************************************\
| Function: CMainWindow::HandlePointerEvent
| Purpose: Handles pointer events for CMainWindow.
| Input: aPointerEvent The pointer event!
| Output: None
\****************************************************************************/
void CMainWindow::HandlePointerEvent (TPointerEvent& aPointerEvent)
{
switch (aPointerEvent.iType)
{
case TPointerEvent::EButton1Down:
break;
case TPointerEvent::EButton1Up:
break;
case TPointerEvent::EButton3Down:
break;
default:
break;
}
}
//////////////////////////////////////////////////////////////////////////////
// CExampleWsClient implementation
//////////////////////////////////////////////////////////////////////////////
CExampleWsClient* CExampleWsClient::NewL(const TRect& aRect)
{
// make new client
CExampleWsClient* client=new (ELeave) CExampleWsClient(aRect);
CleanupStack::PushL(client); // push, just in case
client->ConstructL(); // construct and run
CleanupStack::Pop();
return client;
}
/****************************************************************************\
| Function: Constructor/Destructor for CExampleWsClient
| Destructor deletes everything that was allocated by
| ConstructMainWindowL()
\****************************************************************************/
CExampleWsClient::CExampleWsClient(const TRect& aRect)
:iRect(aRect)
{
}
CExampleWsClient::~CExampleWsClient ()
{
delete iMainWindow;
delete iSprite;
}
/****************************************************************************\
| Function: CExampleWsClient::ConstructMainWindowL()
| Called by base class's ConstructL
| Purpose: Allocates and creates all the windows owned by this client
| (See list of windows in CExampleWsCLient declaration).
\****************************************************************************/
void CExampleWsClient::ConstructMainWindowL()
{
iMainWindow=new (ELeave) CMainWindow(this);
iMainWindow->ConstructL(iRect, TRgb (255,255,255));
iSprite=new (ELeave) CSprite (this);
iSprite->ConstructL(iMainWindow);
}
/****************************************************************************\
| Function: CExampleWsClient::RunL()
| Called by active scheduler when an even occurs
| Purpose: Processes events according to their type
| For key events: calls HandleKeyEventL() (global to client)
| For pointer event: calls HandlePointerEvent() for window
| event occurred in.
\****************************************************************************/
void CExampleWsClient::RunL()
{
// get the event
iWs.GetEvent(iWsEvent);
TInt eventType=iWsEvent.Type();
// take action on it
switch (eventType)
{
// events global within window group
case EEventNull:
break;
case EEventKey:
{
TKeyEvent& keyEvent=*iWsEvent.Key(); // get key event
HandleKeyEventL (keyEvent);
break;
}
case EEventModifiersChanged:
break;
case EEventKeyUp:
case EEventKeyDown:
case EEventFocusLost:
case EEventFocusGained:
case EEventSwitchOn:
case EEventPassword:
case EEventWindowGroupsChanged:
case EEventErrorMessage:
break;
// events local to specific windows
case EEventPointer:
{
CWindow* window=(CWindow*)(iWsEvent.Handle()); // get window
TPointerEvent& pointerEvent=*iWsEvent.Pointer();
window->HandlePointerEvent (pointerEvent);
break;
}
case EEventPointerExit:
case EEventPointerEnter:
break;
case EEventPointerBufferReady:
{
break;
}
case EEventDragDrop:
break;
default:
break;
}
IssueRequest(); // maintain outstanding request
}
/****************************************************************************\
| Function: CExampleWsClient::HandleKeyEventL()
| Purpose: Processes key events for CExampleWsClient
\****************************************************************************/
void CExampleWsClient::HandleKeyEventL (TKeyEvent& /*aKeyEvent*/)
{
}
// AppHolder.h
//
#ifndef __APPHOLDER_H
#define __APPHOLDER_H
#include <coeccntx.h>
#include <eikenv.h>
#include <eikappui.h>
#include <eikapp.h>
#include <eikdoc.h>
#include <eikmenup.h>
#include <eikon.hrh>
const TUid KUidAppholder = { 0x100098e7 };
class CWsClient;
//
// CAppholderAppUi
//
class CAppholderAppUi : public CEikAppUi
{
public:
void ConstructL();
~CAppholderAppUi();
private: // from CEikAppUi
void HandleCommandL(TInt aCommand);
private:
CWsClient* iClient;
};
//
// CAppholderDocument
//
class CAppholderDocument : public CEikDocument
{
public:
// construct/destruct
CAppholderDocument(CEikApplication& aApp);
~CAppholderDocument();
private: // from CEikDocument
CEikAppUi* CreateAppUiL();
};
//
// CAppholderApplication
//
class CAppholderApplication : public CEikApplication
{
private: // from CApaApplication
CApaDocument* CreateDocumentL();
TUid AppDllUid() const;
};
#endif
// Base.h
//
// Copyright (c) 2005 Symbian Softwares Ltd. All rights reserved.
//
#if !defined(__VECTORSPRITES_H__)
#define __VECTORSPRITES_H__
// Forward declarations
class CWsRedrawer;
class CWindow;
/////////////////////////////////////////////////////////////////////////
// Declaration of CWsClient
/////////////////////////////////////////////////////////////////////////
class CWsClient : public CActive
{
public:
void ConstructL();
// destruct
~CWsClient();
// main window
virtual void ConstructMainWindowL();
// terminate cleanly
void Exit();
// active object protocol
void IssueRequest(); // request an event
void DoCancel(); // cancel the request
virtual void RunL() = 0; // handle completed request
virtual void HandleKeyEventL (TKeyEvent& aKeyEvent) = 0;
protected:
//construct
CWsClient();
CWsScreenDevice* iScreen;
CWsRedrawer* iRedrawer;
RWsSession iWs;
TWsEvent iWsEvent;
private:
RWindowGroup iGroup;
CWindowGc* iGc;
friend class CWsRedrawer; // needs to get at session
friend class CWindow; // needs to get at session
friend class CSprite;
friend class CPointerCursor;
};
////////////////////////////////////////////////////////////////////////////
// CWsRedrawer declaration
////////////////////////////////////////////////////////////////////////////
class CWsRedrawer : public CActive
{
public:
// construct/destruct
CWsRedrawer();
void ConstructL(CWsClient* aClient);
~CWsRedrawer();
// drawing
void IssueRequest();
void DoCancel();
void RunL();
protected:
CWsClient* iClient;
};
//////////////////////////////////////////////////////////////////////////////
// CWindow declaration
//////////////////////////////////////////////////////////////////////////////
class CWindow : public CBase
{
public:
enum {KPointerMoveBufferSize=32};
CWindow(CWsClient* aClient);
void ConstructL (const TRect& aRect, const TRgb& aColor, CWindow* aParent=0);
~CWindow();
// access
RWindow& Window(); // our own window
CWindowGc* SystemGc(); // system graphics context
CWsScreenDevice* Screen();
CFont* Font();
// drawing
virtual void Draw(const TRect& aRect) = 0;
virtual void HandlePointerEvent (TPointerEvent& aPointerEvent) = 0;
protected:
RWindow iWindow; // window server window
TRect iRect; // window's extent
private:
CWsClient* iClient; // client including session and group
CFont* iFont;
};
#endif
// VectorSprite.H
//
// Copyright (c) 2005 Symbian Softwares Ltd. All rights reserved.
//
#if !defined(__WSPRIT11_H__)
#define __WSPRIT11_H__
#include "Base.h"
// CMainWindow is a plain window that just acts as a container for the
// other windows
class CMainWindow : public CWindow
{
public:
CMainWindow (CWsClient* aClient);
~CMainWindow ();
void Draw (const TRect& aRect);
void HandlePointerEvent (TPointerEvent& aPointerEvent);
void HandlePointerMoveBufferReady ();
};
//////////////////////////////////////////////////////////////////////////
// Derived client class
//////////////////////////////////////////////////////////////////////////
class CSprite;
class CExampleWsClient : public CWsClient
{
public:
static CExampleWsClient* NewL(const TRect& aRect);
private:
CExampleWsClient (const TRect& aRect);
void ConstructMainWindowL();
~CExampleWsClient ();
void RunL ();
void HandleKeyEventL (TKeyEvent& aKeyEvent);
private:
CMainWindow* iMainWindow;
CSprite* iSprite;
const TRect& iRect;
};
class CSprite : public CBase
{
public:
CSprite (CWsClient* aClient);
~CSprite ();
void ConstructL(CWindow* aWindow);
void CreateBitmap(CFbsBitmap* &aBitmap, TInt aSpriteNum, TBool aDoMask);
private:
CWsClient* iClient;
RWsSprite iSprite;
TSpriteMember iSpriteMember[4];
};
#endif
// VectorSprite.mmp
//
// Copyright (c) 2005 Symbian Softwares Ltd. All rights reserved.
//
// From 9.1 builds supporting EKA2 with Winscw, os will treat all
// applications with the extension exe.
TARGET VectorSprite.exe
TARGETTYPE exe
UID 0x100098e7
VENDORID 0x70000001
SOURCEPATH .
SOURCE AppHolder.cpp Base.cpp VectorSprite.cpp
USERINCLUDE .
SYSTEMINCLUDE \epoc32\include
SYSTEMINCLUDE \epoc32\include\techview
// To support the new resource compilation practice from 9.1
// provide the following details to generate .rss files
START RESOURCE VectorSprite.rss
TARGET VectorSprite.rsc
TARGETPATH \Resource\Apps
HEADER
LANG 01 // Build English language versions
END
// In v8.1, both aif files and registration files are supported,
// but from v9.0 onwards, only registration files are supported.
start resource VectorSprite_reg.rss
targetpath \private\10003a3f\apps
//lang 01
end
// To support localisation for the UI applicatons
start resource VectorSprite_loc.rss
//targetpath \resource\apps
lang 01
end
LIBRARY euser.lib
LIBRARY apparc.lib
LIBRARY cone.lib
LIBRARY eikcore.lib
LIBRARY ws32.lib
LIBRARY bitgdi.lib
LIBRARY gdi.lib
LIBRARY fbscli.lib
// VectorSprite.rss
//
NAME MEAD
#include <eikon.rh>
#include <eikcore.rsg>
RESOURCE RSS_SIGNATURE { }
RESOURCE TBUF
{
buf = "";
}
RESOURCE EIK_APP_INFO
{
menubar = r_appholder_menubar;
hotkeys = r_appholder_hotkeys;
}
RESOURCE HOTKEYS r_appholder_hotkeys
{
control =
{
HOTKEY
{
command = EEikCmdExit;
key = 'e';
}
};
}
RESOURCE MENU_BAR r_appholder_menubar
{
titles =
{
MENU_TITLE
{
menu_pane = r_appholder_file_menu;
txt = "File";
}
};
}
RESOURCE MENU_PANE r_appholder_file_menu
{
items =
{
MENU_ITEM
{
command = EEikCmdExit;
txt = "Close";
}
};
}
#include <appinfo.rh>
RESOURCE LOCALISABLE_APP_INFO
{
short_caption = "VectorSprite";
caption_and_icon =
{
CAPTION_AND_ICON_INFO
{
caption = "VectorSprite";
number_of_icons = 0; // each icon must be a bitmap/mask pair
}
};
}
// Vectorsprite.RSS
//
// Copyright (c) 2005 Symbian Software Ltd. All rights reserved.
//
#include <appinfo.rh>
UID2 KUidAppRegistrationResourceFile
UID3 0x100098e7
RESOURCE APP_REGISTRATION_INFO
{
app_file = Vectorsprite;
localisable_resource_file="\\resource\\apps\\Vectorsprite_loc.rss";
hidden=KAppNotHidden;
embeddability=KAppNotEmbeddable;
newfile=KAppDoesNotSupportNewFile;
launch=KAppLaunchInForeground;
}
The VectorSprite
example creates a simple animated sprite
(a rotating line), and creates the sprite's bitmaps by creating and drawing to
off-screen bitmaps within the application. No redraw events are caused by the
sprite.
CSprite
: Demonstrates how to use class
RWsSprite
by setting up the sprite members to contain bitmaps then
appending them to the sprite. The bitmaps are off screen bitmaps drawn to using
a graphics context.
RWsSpriteBase
: Abstract base class for sprites
RWsSprite
: Sprite
struct TSpriteMember
: Sprite member
CFbsBitmap
: Font-bitmap server bitmap
CFbsBitmapDevice
: FBS bitmap used as graphics device
CGraphicsContext
: Graphics context for drawing