Symbian
Symbian OS Library

SYMBIAN OS V9.3

[Index] [Spacer] [Previous] [Next]



GraphicsShell: drawing and zooming

Note: This example is designed to work with TechView and there is no guarantee that it will work with other interfaces.

The files reproduced here are the main files contained in the examples directory. Some extra files may be needed to run the examples, and these will be found in the appropriate examples directory.


Example Code

The files reproduced here are the main files contained in the examples directory. Some extra files may be needed to run the examples, and these will be found in the appropriate examples directory.

// GraphicsShell.h
//
// Copyright (c) 2000 Symbian Ltd.  All rights reserved.

#ifndef __GraphicsShell_H
#define __GraphicsShell_H

#include <coecntrl.h>
#include <coeccntx.h>

#include <eikappui.h>
#include <eikapp.h>
#include <eikdoc.h>

#include "GraphicsControl.h"

// UID of app

const TUid KUidExampleShellApp={ 0x10004289 };

//
// TExampleShellModel
//

class TExampleShellModel
    {
public:
    TExampleShellModel();
    TBool Differs(const TExampleShellModel* aCompare) const;
public:
    TFileName iLibrary; // active control
    };

//
// class CExampleShellContainer
//

class CExampleShellContainer : public CCoeControl,
        public MCoeControlBrushContext,
        public MGraphicsExampleObserver
    {
public:
    void ConstructL(const TRect& aRect, TExampleShellModel* aModel);
    ~CExampleShellContainer();
    // changing view
    void ResetExampleL(CGraphicExampleControl* aExample);
private: // from CCoeControl
    void Draw(const TRect& /*aRect*/) const;
    TKeyResponse OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType);
    TInt CountComponentControls() const;
    CCoeControl* ComponentControl(TInt aIndex) const;
private: // from MGraphicsExampleObserver
    void NotifyGraphicExampleFinished();
public: // also from MGraphicsExampleObserver
    void NotifyStatus(const TDesC& aMessage);
private: // new function
    void CreateLabelL();
private: // data
    CGraphicExampleControl* iExampleControl; // example control
    CEikLabel* iLabel; // label for status messages
    // irrelevant
    TExampleShellModel* iModel;
    };

//
// CExampleShellDocument
//

class CExampleShellDocument : public CEikDocument
    {
public:
    CExampleShellDocument(CEikApplication& aApp): CEikDocument(aApp) { }
    TExampleShellModel* Model() { return(&iModel); }
private: // from CEikDocument
    CEikAppUi* CreateAppUiL();
private:
    TExampleShellModel iModel;
    };

//
// CExampleShellAppUi
//

class CExampleShellAppUi : public CEikAppUi
    {
public:
    void ConstructL();
    ~CExampleShellAppUi();
private: // from CEikAppUi
    void HandleCommandL(TInt aCommand);
private: // internal use
//  void PrepareToolbarButtons();
private:
    CExampleShellContainer* iContainer;
    TExampleShellModel* iModel;
    };

//
// CExampleShellApplication
//

class CExampleShellApplication : public CEikApplication
    {
private: // from CApaApplication
    CApaDocument* CreateDocumentL();
    TUid AppDllUid() const;
    };

#endif

// GraphicsControl.h
//
// Copyright (c) 2000 Symbian Ltd.  All rights reserved.

#ifndef __GraphicsControl_H
#define __GraphicsControl_H

#include <coecntrl.h>
#include <s32file.h>
#include "CommonGraphicsControlFramework.h"

// sundry derived classes


class CDrawControl : public CGraphicExampleControl
    {
public:
    CDrawControl() { SetMaxPhases(26); };
    void UpdateModelL();
    void Draw(const TRect& aRect) const;
    };

class CZoomControl : public CGraphicExampleControl
    {
public:
    CZoomControl() { SetMaxPhases(5); };
    ~CZoomControl() { delete(iBitmap); };
    void UpdateModelL();
    void Draw(const TRect& aRect) const;
    void DrawLeft(TRect screenRect,CWindowGc& gc) const;
    void DrawRight(TRect screenRect,CWindowGc& gc) const;
private:
    void LoadBitmapL(CFbsBitmap* aBitMap,const TDesC& aPathAndFile,TInt aId,TBool aShareIfLoaded);
private:
    TZoomFactor iLeftZf;
    TZoomFactor iRightZf;
    MGraphicsDeviceMap* iLeftMap;
    MGraphicsDeviceMap* iRightMap;
    CFbsBitmap* iBitmap;
    };


#endif

// Draw.cpp
//
// Copyright (c) 2000 Symbian Ltd.  All rights reserved.

#include "GraphicsControl.h"

#include <coemain.h>

// Text printed to the console in UpdateModeL()
_LIT(KTxtUpdateModelCase0,"point in center of screen");
_LIT(KTxtUpdateModelCase1,"bolder point in center of screen");
_LIT(KTxtUpdateModelCase2,"really bold point in center of screen");
_LIT(KTxtUpdateModelCase3,"a line");
_LIT(KTxtUpdateModelCase4,"a thicker line");
_LIT(KTxtUpdateModelCase5,"really thick - note round ends and clipping");
_LIT(KTxtUpdateModelCase6,"dotted line");
_LIT(KTxtUpdateModelCase7,"dot-dash line");
_LIT(KTxtUpdateModelCase8,"triangle using relative drawing");
_LIT(KTxtUpdateModelCase9,"thick triangle - note rounded corners");
_LIT(KTxtUpdateModelCase10,"dotted triangle - note pattern continuation");
_LIT(KTxtUpdateModelCase11,"centered ellipse");
_LIT(KTxtUpdateModelCase12,"arc - part of ellipse");
_LIT(KTxtUpdateModelCase13,"arc - other part - see also construction elements");
_LIT(KTxtUpdateModelCase14,"pie slices");
_LIT(KTxtUpdateModelCase15,"centered rectangle with rounded corners");
_LIT(KTxtUpdateModelCase16,"rounded rectangle showing corner ellipse");
_LIT(KTxtUpdateModelCase17,"polyline");
_LIT(KTxtUpdateModelCase18,"polygon with winding-fill rule");
_LIT(KTxtUpdateModelCase19,"polygon using alternate-fill rule");
_LIT(KTxtUpdateModelCase20,"copying using CopyRect()");
_LIT(KTxtUpdateModelCase21,"left-justified boxed text");
_LIT(KTxtUpdateModelCase22,"centered boxed text");
_LIT(KTxtUpdateModelCase23,"right-justified offset text");
_LIT(KTxtUpdateModelCase24,"cross-hatched box");
_LIT(KTxtUpdateModelCase25,"teeny preview font!");
_LIT(KTxtUpdateModelDefault,"overran!");
    
void CDrawControl::UpdateModelL()
    {
    switch (Phase())
        {
        case 0:
            iGraphObserver->NotifyStatus(KTxtUpdateModelCase0);
            break;
        case 1:
            iGraphObserver->NotifyStatus(KTxtUpdateModelCase1);
            break;
        case 2:
            iGraphObserver->NotifyStatus(KTxtUpdateModelCase2);
            break;
        case 3:
            iGraphObserver->NotifyStatus(KTxtUpdateModelCase3);
            break;
        case 4:
            iGraphObserver->NotifyStatus(KTxtUpdateModelCase4);
            break;
        case 5:
            iGraphObserver->NotifyStatus(KTxtUpdateModelCase5);
            break;
        case 6:
            iGraphObserver->NotifyStatus(KTxtUpdateModelCase6);
            break;
        case 7:
            iGraphObserver->NotifyStatus(KTxtUpdateModelCase7);
            break;
        case 8:
            iGraphObserver->NotifyStatus(KTxtUpdateModelCase8);
            break;
        case 9:
            iGraphObserver->NotifyStatus(KTxtUpdateModelCase9);
            break;
        case 10:
            iGraphObserver->NotifyStatus(KTxtUpdateModelCase10);
            break;
        case 11:
            iGraphObserver->NotifyStatus(KTxtUpdateModelCase11);
            break;
        case 12:
            iGraphObserver->NotifyStatus(KTxtUpdateModelCase12);
            break;
        case 13:
            iGraphObserver->NotifyStatus(KTxtUpdateModelCase13);
            break;
        case 14:
            iGraphObserver->NotifyStatus(KTxtUpdateModelCase14);
            break;
        case 15:
            iGraphObserver->NotifyStatus(KTxtUpdateModelCase15);
            break;
        case 16:
            {
            iGraphObserver->NotifyStatus(KTxtUpdateModelCase16);
            }
            break;
        case 17:
            iGraphObserver->NotifyStatus(KTxtUpdateModelCase17);
            break;
        case 18:
            iGraphObserver->NotifyStatus(KTxtUpdateModelCase18);
            break;
        case 19:
            iGraphObserver->NotifyStatus(KTxtUpdateModelCase19);
            break;
        case 20:
            {
            iGraphObserver->NotifyStatus(KTxtUpdateModelCase20);
            }
            break;
        case 21:
            iGraphObserver->NotifyStatus(KTxtUpdateModelCase21);
            break;
        case 22:
            iGraphObserver->NotifyStatus(KTxtUpdateModelCase22);
            break;
        case 23:
            iGraphObserver->NotifyStatus(KTxtUpdateModelCase23);
            break;
        case 24:
            iGraphObserver->NotifyStatus(KTxtUpdateModelCase24);
            break;
        case 25:
            iGraphObserver->NotifyStatus(KTxtUpdateModelCase25);
            break;
        default:
            iGraphObserver->NotifyStatus(KTxtUpdateModelDefault);
            break;
        }
    }


// Text printed to the console in UpdateModeL()
_LIT(KTxtDrawCase21,"White text left justified in dark gray box");
_LIT(KTxtDrawCase22,"White text centered in black box");
_LIT(KTxtDrawCase23,"Dark gray text right justified in lite gray box");
_LIT(KTxtDrawCase25,"This text overwrites the cleared area");

    
void CDrawControl::Draw(const TRect& /* aRect */) const
    {
    // put the next line back in to see the individual drawing actions
    // (iCoeEnv->WsSession()).SetAutoFlush(ETrue);
    // draw surrounding rectangle
    CWindowGc& gc=SystemGc(); // graphics context we draw to
    gc.UseFont(iMessageFont); // use the system message font
    gc.Clear();
    SystemGc().DrawRect(Rect()); // surrounding rectangle to draw into
    TRect rect=Rect(); // a centered rectangle of the default size
    TRect ellipseRect=Rect(); // for arcs and ellipse
    ellipseRect.Shrink(10,10); // set size so inside the border rectangle
    TRect box=Rect(); // a smaller centered rectangle, for text in a box
    box.Shrink(10,10); // set size of text box
    TRect tinyBox=Rect(); // a tiny box to clear
    tinyBox.Shrink(220,90); // set size of tiny box to clear
    TInt offset=0; // offset, for text in a box
    TPoint screenCenterPoint=rect.Center(); // the center of the screen 
    // set up a pair of construction points for arc and pie slice drawing
    // set up the size for half a screen (divided vertically)
    TPoint constructionPoint1(15,15); // outside the construction ellipse
    TPoint constructionPoint2(200,150); // inside the construction ellipse
    // set up a pair of points for drawing diagonal lines
    TPoint startPoint(50,50);
    TPoint endPoint(590,190);
    // set up an array of points for drawing a polyline and a polygon etc
    // will be used relative to top left of rectangle
    TPoint point1(20,20);
    TPoint point2(100,190);
    TPoint point3(110,90);
    TPoint point4(50,150);
    TPoint point5(200,150);
    CArrayFix<TPoint>* mypoints;
    mypoints = new CArrayFixFlat<TPoint>(5);
    mypoints->AppendL(point1);
    mypoints->AppendL(point2);
    mypoints->AppendL(point3);
    mypoints->AppendL(point4);
    mypoints->AppendL(point5);
    // set up a black, a dark gray, a lite gray and a white RGB color
    TRgb black(0,0,0);
    TRgb darkGray(85,85,85);
    TRgb liteGray(170,170,170);
    TRgb white(255,255,255); // appears as blank screen gray-green color
    // Set up a "bold" size for the pen tip to (default is 1,1)
    TSize penSizeBold(3,3);
    // Set up a "fat" size for the pen tip
    TSize penSizeFat(30,30);
    // decide what to do, and do it
    switch (Phase())
        {
        case 0:
            // draw a single pixel point in the center of the screen
            // it is so small that some text is needed to explain the screen...
            gc.Plot(screenCenterPoint);
            break;
        case 1:
            // draw a "bold" point 3 pixels across
           gc.SetPenSize(penSizeBold);
            gc.Plot(screenCenterPoint);
            break;
        case 2:
            // draw a "fat" point (circular blob),
            // illustrating the effect of a very wide pen
           gc.SetPenSize(penSizeFat);
            gc.Plot(screenCenterPoint);
            break;
        case 3:
            // draw a thin line fromtop left to bottom right
            gc.DrawLine(startPoint,endPoint);
            break;
        case 4:
            // draw a "bold" line fromtop left to bottom right
           gc.SetPenSize(penSizeBold);
            gc.DrawLine(startPoint,endPoint);
            break;
        case 5:
            // draw a rather wide line from top left to bottom right,
            // illustrating rounded ends and their clipping
           gc.SetPenSize(penSizeFat);
            gc.DrawLine(startPoint,endPoint);
            break;
        case 6:
            // draw a dotted line from top left to bottom right
            gc.SetPenStyle(CGraphicsContext::EDottedPen);
            gc.DrawLine(startPoint,endPoint);
            break;
        case 7:
            // draw a dot-dash line from top left to bottom right
            gc.SetPenStyle(CGraphicsContext::EDotDashPen);
            gc.DrawLine(startPoint,endPoint);
            break;
        case 8:
            // draw a triangle by relative drawing
            gc.MoveTo(TPoint(300,50)); // drawing position (300,50)
            gc.DrawLineBy(TPoint(205,100)); // drawing position (505,150)
            gc.DrawLineBy(TPoint(-410,0)); // drawing position (95,150)
            gc.DrawLineBy(TPoint(205,-100)); // drawing position (300,50)
            break;
        case 9:
           // draw a triangle, by relative drawing
           // illustrating rounded ends at corners when using very wide lines
            gc.SetPenSize(penSizeFat);
            gc.MoveTo(TPoint(300,50)); // drawing position (300,50)
            gc.DrawLineBy(TPoint(205,100)); // drawing position (505,150)
            gc.DrawLineBy(TPoint(-410,0)); // drawing position (95,150)
            gc.DrawLineBy(TPoint(205,-100)); // drawing position (300,50)
            break;
        case 10:
            // draw a triangle by sequential drawing between specified points,
            // using dot-dash line style, illustrating line pattern continuation 
            gc.SetPenStyle(CGraphicsContext::EDotDashPen);
            gc.MoveTo(TPoint(300,50)); // drawing position (300,50)
            gc.DrawLineTo(TPoint(505,150)); // drawing position (505,150)
            gc.DrawLineTo(TPoint(95,150)); // drawing position (95,150)
            gc.DrawLineTo(TPoint(300,50)); // drawing position (300,50)
            break;
        case 11:
            // draw an ellipse centered in the rectangle
            gc.DrawEllipse(ellipseRect);
            break;
        case 12:
            // draw an arc centered in the rectangle
            gc.DrawArc(ellipseRect,constructionPoint1,constructionPoint2);
            // gc.Clear();
            break;
        case 13:
            // draw an arc centered in the rectangle that is the other
            // portion of the ellipse (arguments reversed)
            gc.DrawArc(ellipseRect,constructionPoint2,constructionPoint1);
            // draw construction lines and points
            gc.SetPenStyle(CGraphicsContext::EDottedPen);
            gc.MoveTo(constructionPoint1);
            gc.DrawLineTo(screenCenterPoint);
            gc.DrawLineTo(constructionPoint2);
           gc.SetPenSize(penSizeBold);
            gc.Plot(constructionPoint1);
            gc.Plot(constructionPoint2);
            gc.Plot(screenCenterPoint);
            break;
        case 14:
            // draw a pie slice centered in the rectangle
            gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
            gc.SetBrushColor(white);
            gc.DrawPie(ellipseRect,constructionPoint1,constructionPoint2);
            // draw the other portion of the elliptical disc
            gc.SetBrushStyle(CGraphicsContext::EVerticalHatchBrush);
            gc.DrawPie(ellipseRect,constructionPoint2,constructionPoint1);
            break;
        case 15:
            {
            // draw a rectangle with rounded corners, centered in the rectangle
            TSize cornerSize(20,20); // size of a rounded corner
            gc.DrawRoundRect(box,cornerSize); // same rect as text box
            }
            break;
        case 16:
            {
            // draw a rectangle with rounded corners,
            //centered in the rectangle, showing a corner ellipse
            TSize cornerSize(20,20); // size of a rounded corner
            // rect for corner ellipse is twice the corner size
            TSize cornerEllipseSize(cornerSize.iHeight*2,cornerSize.iWidth*2);
            TRect cornerRectTl(box.iTl,cornerEllipseSize);
            gc.DrawRoundRect(box,cornerSize);
            gc.SetPenStyle(CGraphicsContext::EDottedPen);
            gc.DrawEllipse(cornerRectTl); // corner construction ellipse
            }
            break;
        case 17:
            // draw a polyline
            gc.DrawPolyLine(mypoints);
            break;
        case 18:
            // draw self-crossing polygon using the winding fill rule
            gc.SetBrushStyle(CGraphicsContext::ESquareCrossHatchBrush);
            gc.SetBrushColor(black);
            gc.DrawPolygon(mypoints,CGraphicsContext::EWinding);
            break;
        case 19:
            // draw self-crossing polygon using the alternate fill rule
            gc.SetBrushStyle(CGraphicsContext::EDiamondCrossHatchBrush);
            gc.SetBrushColor(black);
            gc.DrawPolygon(mypoints,CGraphicsContext::EAlternate);
            break;
        case 20:
            {
            // draw self-crossing polygon using the alternate fill rule,
            // and copy the lhs to the rhs of the screen
            gc.SetBrushStyle(CGraphicsContext::EDiamondCrossHatchBrush);
            gc.SetBrushColor(black);
            gc.DrawPolygon(mypoints,CGraphicsContext::EAlternate);
            TPoint screenOrigin(0,0); // top left of the screen
            TSize halfScreenLR(320,240); // size of vertical half of screen
            rect.SetRect(screenOrigin,halfScreenLR); // lhs of screen
            TPoint offset(halfScreenLR.iWidth,0); // half screen width offset
            gc.CopyRect(offset,rect); //  copy lhs of screen to rhs
            }
            break;
        case 21:
            // draw some text left justified in a box,
            // offset so text is just inside top of box
            {
            CFont* font=iMessageFont; // get the system message font
            TInt fontAscent(font->AscentInPixels()); // system message font ascent
            offset=fontAscent+3; // add a 3 pixel text line spacing
            TInt margin=2; // left margin is two pixels
            gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
            gc.SetBrushColor(darkGray);
            gc.SetPenColor(white);
            gc.UseFont(iMessageFont);
            gc.DrawText(KTxtDrawCase21,box,offset,CGraphicsContext::ELeft,margin);
            }
            break;
        case 22:
            // draw some text centered in a box, (margin is zero)
            {
            TInt boxHeight=box.Height(); // get height of text box
            CFont* font=iMessageFont; // get the system message font
            TInt textHeight(font->HeightInPixels()); // system message font height
            offset=(textHeight+boxHeight)/2; // 1/2 font ht below halfway down box
            TInt margin=0; // margin is zero
            gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
            gc.SetBrushColor(black);
            gc.SetPenColor(white);
            gc.UseFont(iMessageFont);
            gc.DrawText(KTxtDrawCase22,box,offset,CGraphicsContext::ECenter,margin);
            }
            break;
        case 23:
            // draw some text right justified in a box,
            // offset so text is just inside bottom of box
            {
            TInt boxHeight=box.Height(); // get height of text box
            CFont* font=iMessageFont; // get the system message font
            TInt fontDescent=font->DescentInPixels(); // system message font descent
            offset=boxHeight-fontDescent-3;// offset, 3 pixel text line spacing 
            TInt margin=2; // right margin is two pixels
            gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
            gc.SetBrushColor(liteGray);
            gc.SetPenColor(darkGray);
            gc.UseFont(iMessageFont);
            gc.DrawText(KTxtDrawCase23,box,offset,CGraphicsContext::ERight,margin);
            }
            break;
        case 24:
            {
            // draw a cross-hatched box
            // then clear a small central rectangle
            gc.SetBrushColor(darkGray);
            gc.SetBrushStyle(CGraphicsContext::ESquareCrossHatchBrush);
            gc.DrawRect(rect);
            // clear a small rectangle
            gc.SetBrushColor(liteGray); // change the brush color
            gc.Clear(tinyBox); // clear to brush color
            }
            break;
        case 25:
            {
            // draw a cross-hatched box
            // then clear a small central rectangle
            // and write some text in it in smallest Swiss font,
            // (which is actually a tiny "block" print-preview font)
            // starting bottom left (illustrating flicker, overlap, mess)
            gc.SetBrushColor(darkGray);
            gc.SetBrushStyle(CGraphicsContext::ESquareCrossHatchBrush);
            gc.DrawRect(rect);
            // clear a small rectangle
            gc.SetBrushColor(liteGray); // change the brush color
            gc.Clear(tinyBox); // clear to brush color
            // get an alternative font
            CFont* myFont;
            _LIT(KTxtArial,"Arial");
            TFontSpec myFontSpec(KTxtArial,1); // to get smallest Arial font
            CGraphicsDevice* screenDevice=(iCoeEnv->ScreenDevice());
            screenDevice->GetNearestFontInTwips(myFont,myFontSpec);
            gc.UseFont(myFont);
            // set the text drawing position & draw (demonstrating flicker)
            TInt fontDescent=myFont->DescentInPixels();
            TPoint pos(0,tinyBox.Height()-fontDescent);
            pos+=tinyBox.iTl;
            gc.DrawText(KTxtDrawCase25,pos);
            // discard and destroy the font
            gc.DiscardFont();
            screenDevice->ReleaseFont(myFont);
            }
            break;
        default:
            break;
        }
    delete mypoints; // an array must be destroyed after use
     }

//
// Copyright (c) 2000 Symbian Ltd.  All rights reserved.

#include "GraphicsControl.h"

#include <coemain.h>
#include <coeaui.h>

_LIT(KtxtSwiss,"Swiss");

void CGraphicExampleControl::ConstructL(const TRect& aRect, MGraphicsExampleObserver* aGraphObserver, 
                                        const CCoeControl& aParent)
    {
    // remember the graphics observer
    iGraphObserver=aGraphObserver;
    // create window
    CreateWindowL(&aParent);
    // construct font for messages
    TFontSpec spec(KtxtSwiss,213);
    iMessageFont=iCoeEnv->CreateScreenFontL(spec);
    // set rectangle to prescription
    SetRect(aRect);
    // go for it
    ActivateL();
    UpdateModelL(); // phase 0
    }

CGraphicExampleControl::~CGraphicExampleControl()
    {
    iCoeEnv->ReleaseScreenFont(iMessageFont);
    }

void CGraphicExampleControl::Quit()
    {
    iGraphObserver->NotifyGraphicExampleFinished();
    }

void CGraphicExampleControl::NextPhaseL()
    {
    if (++iPhase >= iMaxPhases)
        Quit();
    else
        {
        UpdateModelL();
        DrawNow();
        }
    }

void CGraphicExampleControl::HandlePointerEventL(const TPointerEvent& aPointerEvent)
    {
    if (aPointerEvent.iType==TPointerEvent::EButton1Down) NextPhaseL();
    }

TKeyResponse CGraphicExampleControl::OfferKeyEventL(
            const TKeyEvent& aKeyEvent,TEventCode aType
            )
    {
    if (aType!=EEventKey) return EKeyWasNotConsumed;
    TInt code=aKeyEvent.iCode;
    switch (code)
        {
        case ' ':
            NextPhaseL();
            break;
        default:
            return EKeyWasNotConsumed;
        }
    return EKeyWasConsumed;
    }

// GraphicsShell.cpp
//
// Copyright (c) 2000-2005 Symbian Software Ltd.  All rights reserved.

#include <e32keys.h>

#include <coemain.h>

#include <eikenv.h>
#include <eikdef.h>
#include <eikon.hrh>
#include <eiklabel.h>
#include <eikstart.h>

#include <GraphicsShell.rsg>
#include "GraphicsShell.hrh"
#include "GraphicsShell.h"


//
// TExampleShellModel
//

TExampleShellModel::TExampleShellModel()
    {
    iLibrary=KNullDesC;
    }

TBool TExampleShellModel::Differs(const TExampleShellModel* aCompare) const
    {
    return((*(TInt32*)this)!=(*(TInt32*)aCompare));
    }

//
// class CExampleShellContainer
//

void CExampleShellContainer::ConstructL(const TRect& aRect, TExampleShellModel* aModel)
    {
    iModel=aModel;
    CreateWindowL();
    Window().SetShadowDisabled(ETrue);
    iContext=this;
     iBrushStyle=CGraphicsContext::ESolidBrush;
    iBrushColor=KRgbWhite;
    SetRect(aRect);
    CreateLabelL();
    ActivateL();
    }

CExampleShellContainer::~CExampleShellContainer()
    {
    delete iExampleControl;
    delete iLabel;
    }
    
TInt CExampleShellContainer::CountComponentControls() const
    {
    return 1 + (iExampleControl ? 1 : 0);
    }

CCoeControl* CExampleShellContainer::ComponentControl(TInt aIndex) const
    {
    switch (aIndex)
        {
    case 0: return iLabel;
    case 1: return iExampleControl;
    default: return 0;
        };
    }

const TInt KLabelHeight=20;

void CExampleShellContainer::CreateLabelL()
    {
    iLabel=new (ELeave) CEikLabel;
    TRect rect=Rect();
    rect.iTl.iY=rect.iBr.iY-KLabelHeight; // make it bottom 20 pixels
    iLabel->SetContainerWindowL(*this);
    iLabel->SetRect(rect);
    iLabel->SetAlignment(EHCenterVCenter); // center text
    iLabel->SetBufferReserveLengthL(200); // nice long buffer
    iLabel->SetFont(iEikonEnv->AnnotationFont());
    iLabel->ActivateL(); // now ready
    }

void CExampleShellContainer::ResetExampleL(CGraphicExampleControl* aExample)
    {
    // get rid of old control
    delete iExampleControl;
    // set up new one
    iExampleControl=aExample;
    // if non-zero, then carry on
    if (!iExampleControl) return;
    TRect rect=Rect(); // get our rect
    rect.iBr.iY-=KLabelHeight; // make way for label
    rect.Shrink(2,2); // shrink it a bit
    iExampleControl->ConstructL(rect,this,*this); // construct, giving rect, observer, and parent
    }

_LIT(KTxtFinished,"example finished");
void CExampleShellContainer::NotifyGraphicExampleFinished()
    {
    NotifyStatus(KTxtFinished);
    }

void CExampleShellContainer::NotifyStatus(const TDesC& aMessage)
    {
    iLabel->SetTextL(aMessage);
    if (IsActivated()) iLabel->DrawNow();
    }

TKeyResponse CExampleShellContainer::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
    {
    if  (iExampleControl)
         return iExampleControl->OfferKeyEventL(aKeyEvent,aType);
    else
        return EKeyWasNotConsumed;
    }

void CExampleShellContainer::Draw(const TRect& /*aRect*/) const
    {
    CWindowGc& gc = SystemGc();
    gc.SetPenStyle(CGraphicsContext::ENullPen);
    gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
    gc.DrawRect(Rect());
    }

//
// CExampleShellAppUi
//

_LIT(KTxtInitialized,"initialized");
void CExampleShellAppUi::ConstructL()
    {
    BaseConstructL();
    iModel=((CExampleShellDocument*)iDocument)->Model();
    iContainer=new(ELeave) CExampleShellContainer;
    iContainer->ConstructL(ClientRect(),iModel);
    iContainer->NotifyStatus(KTxtInitialized);
    // add container to stack; enables key event handling.
    AddToStackL(iContainer);
    }

void CExampleShellAppUi::HandleCommandL(TInt aCommand)
    {
    switch (aCommand)
        {
    case EExampleShellSelectDraw:
        iContainer->ResetExampleL(new (ELeave) CDrawControl);
        return;
    case EExampleShellSelectZoom:
        iContainer->ResetExampleL(new (ELeave) CZoomControl);
        return;
    case EEikCmdExit:
        Exit();
        return;
        }
    }

CExampleShellAppUi::~CExampleShellAppUi()
    {
    RemoveFromStack(iContainer);
    delete iContainer;
    }

//
// CExampleShellDocument
//

CEikAppUi* CExampleShellDocument::CreateAppUiL()
    {
    return(new(ELeave) CExampleShellAppUi);
    }

//
// CExampleShellApplication
//

TUid CExampleShellApplication::AppDllUid() const
    {
    return KUidExampleShellApp;
    }

CApaDocument* CExampleShellApplication::CreateDocumentL()
    {
    return new(ELeave) CExampleShellDocument(*this);
    }

//
// EXPORTed functions
//

EXPORT_C CApaApplication* NewApplication()
    {
    return new CExampleShellApplication;
    }


GLDEF_C TInt E32Main()
    {
    return EikStart::RunApplication(NewApplication);
    }

// Zoom.cpp
//
// Copyright (c) 2000-2005 Symbian Software Ltd.  All rights reserved.

#include "GraphicsControl.h"

// header for multi-bitmap file grbitmap.mbm containing 2 bitmaps to use
#include <grbmap2.mbg>

#include <coemain.h>

_LIT(KTxtCDrive,"C:");
_LIT(KTxtZDrive,"Z:");

void CZoomControl::LoadBitmapL(CFbsBitmap* aBitMap,const TDesC& aPathAndFile,TInt aId,TBool aShareIfLoaded)
    {
    TParse mbfn;
    
    mbfn.Set(aPathAndFile,&KTxtCDrive,NULL);
    if (!aBitMap->Load(mbfn.FullName(),aId,aShareIfLoaded))
        return;

    mbfn.Set(aPathAndFile,&KTxtZDrive,NULL);
    User::LeaveIfError(aBitMap->Load(mbfn.FullName(),aId,aShareIfLoaded));
    return;
    }

// Name of the multi-bitmap file containing the bitmap
// and bitmap mask files
_LIT(KTxtFileName,"\\resource\\apps\\grbmap2.mbm");

void CZoomControl::UpdateModelL()
    {
    // set up name for bitmap sharing
    TBool shareIfLoaded(ETrue);

    // set up two zoom factor objects (one for examples, one for commentary)
    iLeftZf.SetGraphicsDeviceMap(iCoeEnv->ScreenDevice());
    iRightZf.SetGraphicsDeviceMap(iCoeEnv->ScreenDevice());
    //iLeftZf.SetDevice(iCoeEnv->ScreenDevice());
    //iRightZf.SetDevice(iCoeEnv->ScreenDevice());
    
    // set the zoom factor of the objects (example is dependent on phase of example, commentary is fixed)
    iLeftZf.SetZoomFactor(TZoomFactor::EZoomOneToOne*2*(Phase()+1)/5);
    iRightZf.SetZoomFactor(TZoomFactor::EZoomOneToOne*2*(5-Phase())/5);

    // use graphics device maps for drawing and getting fonts
    iLeftMap=&iLeftZf;
    iRightMap=&iRightZf;

    if (Phase()==0) {
        iBitmap = new (ELeave) CFbsBitmap();
        LoadBitmapL(iBitmap,KTxtFileName,EMbmGrbmap2Smiley,shareIfLoaded);
    }
    
    // set up descriptor for commentary area
    _LIT(KFormat1,"Left zoom factor=%1.1f:1  Right zoom factor=%1.1f:1");
    TBuf<128> commentaryText;
    TReal leftValue = 2*(Phase()+1)/5.0;
    TReal rightValue = 2*(5-Phase())/5.0;
    commentaryText.Format(KFormat1,leftValue,rightValue);
    iGraphObserver->NotifyStatus(commentaryText);
    };

void CZoomControl::Draw(const TRect& /* aRect */) const
    {
    // setup screen for example: get graphics context and draw surrounding rectangle
    CWindowGc& gc=SystemGc();
    gc.Clear(); 
    
    // create a centered rectangle of the default size
    TRect screenRect=Rect();
    TInt bisect = (screenRect.iBr.iX-screenRect.iTl.iX)/2 + screenRect.iTl.iX;
    TRect leftRect(screenRect.iTl,TPoint(bisect,screenRect.iBr.iY));
    TRect rightRect(TPoint(bisect,screenRect.iTl.iY),screenRect.iBr);

    DrawLeft(leftRect,gc);
    DrawRight(rightRect,gc);
     }


    _LIT(KTxtTimesNewRoman,"Times New Roman");
    _LIT(KTxtGrzoomExampleText,"grzoom example text");

void CZoomControl::DrawLeft(TRect screenRect,CWindowGc& SystemGc) const
    {
    // set up absolute font-spec and text box for 200 twip Times font
    TFontSpec fontSpec(KTxtTimesNewRoman,200);
    // find the nearest font to the specified one
    CFont* screenFont;                                     
    iLeftMap->GetNearestFontInTwips(screenFont,fontSpec);
    // use it for this graphics context
    SystemGc.UseFont(screenFont);
    // get height of screen box
    TInt screenHeight=screenRect.Height();
    // get font height
    TInt textHeight = screenFont->HeightInPixels();
    // 1/2 font height below halfway down box
    TInt exampleOffset=(screenHeight+textHeight)/2;
    TInt exampleMargin=0;
    SystemGc.DrawText(KTxtGrzoomExampleText,screenRect,exampleOffset,CGraphicsContext::ECenter,exampleMargin);
    // discard and release font
    SystemGc.DiscardFont();
    iLeftMap->ReleaseFont(screenFont);   
    
    // set up example box in twips
    TRect boxInTwips(TPoint(0,0),TPoint(500,300));
    // convert rectangle co-ordinates into pixels
    TRect boxInPixels = iLeftMap->TwipsToPixels(boxInTwips);
    SystemGc.DrawRect(boxInPixels);

    // set up rectangle for bitmap to be stretched into
    TRect bitmapRectInTwips(TPoint(0,0),TPoint(500,500));
    TRect bitmapRectInPixels = iLeftMap->TwipsToPixels(bitmapRectInTwips);
    bitmapRectInPixels.iTl.iY+=125;
    bitmapRectInPixels.iBr.iY+=125;
    bitmapRectInPixels.iTl.iX+=100;
    bitmapRectInPixels.iBr.iX+=100;
    // draw the bitmap, stretched into the rectangle
    SystemGc.DrawBitmap(bitmapRectInPixels, iBitmap);
    }

void CZoomControl::DrawRight(TRect screenRect,CWindowGc& SystemGc) const
    {
    // set up colors: black and a white RGB color
    TRgb black(0,0,0);
    TRgb white(255,255,255); // appears as blank screen gray-green color
    SystemGc.SetBrushStyle(CGraphicsContext::ESolidBrush);
    SystemGc.SetBrushColor(black);
    SystemGc.SetPenColor(white);

    // set up absolute font-spec and text box for 200 twip Times font
    TFontSpec fontSpec(KTxtTimesNewRoman,200);
    // find the nearest font to the specified one
    CFont* commentFont;
    iRightMap->GetNearestFontInTwips(commentFont,fontSpec);
    // use it for this graphics context
    SystemGc.UseFont(commentFont);
    // get font height
    TInt textHeight = commentFont->HeightInPixels();
    // get height of text box
    TInt boxHeight=screenRect.Height();
    // 1/2 font height below halfway down box
    TInt commentOffset=(boxHeight+textHeight)/2;
    TInt commentMargin=0;
    // draw text
    SystemGc.DrawText(KTxtGrzoomExampleText,screenRect,commentOffset,CGraphicsContext::ECenter,commentMargin);
    // discard and release font
    SystemGc.DiscardFont();
    iRightMap->ReleaseFont(commentFont);
    
    // set up example box in twips
    TRect boxInTwips(TPoint(0,0),TPoint(500,300));
    // convert rectangle co-ordinates into pixels
    TRect boxInPixels = iRightMap->TwipsToPixels(boxInTwips);
    boxInPixels.Move(screenRect.iTl);
    SystemGc.DrawRect(boxInPixels);

    // set up rectangle for bitmap to be stretched into
    TRect bitmapRectInTwips(TPoint(0,0),TPoint(500,500));
    TRect bitmapRectInPixels = iRightMap->TwipsToPixels(bitmapRectInTwips);
    bitmapRectInPixels.Move(screenRect.iTl);
    bitmapRectInPixels.iTl.iY+=125;
    bitmapRectInPixels.iBr.iY+=125;
    bitmapRectInPixels.iTl.iX+=100;
    bitmapRectInPixels.iBr.iX+=100;
    // draw the bitmap, stretched into the rectangle
    SystemGc.DrawBitmap(bitmapRectInPixels, iBitmap);
    }

// GraphicsShell.hrh
//
// Copyright (c) 2000 Symbian Ltd.  All rights reserved.

enum TExampleMenuCommands
    {
    EExampleShellSelectDraw=400,
    EExampleShellSelectZoom
    };

// BLD.INF
// Component description file 
//
// Copyright (c) 2000 Symbian Ltd.  All rights reserved.

PRJ_MMPFILES

GraphicsShell.mmp

// GraphicsShell.mmp
//
// Copyright (c) 2000-2005 Symbian Software Ltd.  All rights reserved.

// using relative paths for source and userinclude directories

TARGET         GraphicsShell.exe
TARGETTYPE     exe
UID            0x100039ce 0x10004289
VENDORID       0x70000001

SOURCEPATH     .
SOURCE         Zoom.cpp GraphicsShell.cpp GraphicsControl.cpp Draw.cpp 

START RESOURCE GraphicsShell.rss
TARGETPATH     \resource\apps
HEADER
END

USERINCLUDE    .
USERINCLUDE    .\CommonGraphicsExampleFiles
SYSTEMINCLUDE  \Epoc32\include
SYSTEMINCLUDE  \epoc32\include\techview

LIBRARY        euser.lib efsrv.lib gdi.lib ws32.lib fbscli.lib
LIBRARY        cone.lib  apparc.lib eikcore.lib  eikcoctl.lib 

START BITMAP   grbmap2.mbm
TARGETPATH     \resource\apps
HEADER
SOURCE         c8 Smiley.bmp Smilmask.bmp
END 

START RESOURCE GraphicsShell_reg.rss
TARGETPATH     \private\10003a3f\apps
END

// GraphicsShell.rss
//
// Copyright (c) 2000 Symbian Ltd.  All rights reserved.

NAME GRSH

#include <eikon.rh>
#include "GraphicsShell.hrh"

RESOURCE RSS_SIGNATURE { }

RESOURCE TBUF { buf=""; }

RESOURCE EIK_APP_INFO
    {
    menubar=r_grsh_menubar;
    hotkeys=r_grsh_hotkeys;
    }


RESOURCE HOTKEYS r_grsh_hotkeys
    {
    control=
        {
        HOTKEY { command=EEikCmdExit; key='e'; }
        };
    }

RESOURCE MENU_BAR r_grsh_menubar
    {
    titles=
        {
        MENU_TITLE {menu_pane=menu1; txt="File"; },
    MENU_TITLE {menu_pane=menu2; txt="List Of Programs "; }
    };
    }


RESOURCE MENU_PANE menu1
    {
    items=
        {
        MENU_ITEM { command=EEikCmdExit; txt="Exit"; }
        };
    }

RESOURCE MENU_PANE menu2
    {
    items=
        {
        MENU_ITEM { command=EExampleShellSelectDraw; txt="Draw"; },
        MENU_ITEM { command=EExampleShellSelectZoom; txt="Zoom"; }        
        };
    }

GraphicsShell_reg.rss
#include <appinfo.rh>

UID2 KUidAppRegistrationResourceFile
UID3 0x10004289 // application UID
RESOURCE APP_REGISTRATION_INFO
    {
    app_file = "GraphicsShell";
    }

[Top]


Description

GraphicsShell provides an application shell, and two concrete controls.

CGraphicExampleControl is a control class, derived from CCoeControl, which links the app shell to the particular controls.

CDrawControl illustrates the drawing of shapes in a window. The code draws points, lines and shapes; this exercises a variety of drawing functions provided by the window graphics context such as MoveTo(), DrawLineTo(), DrawArc() etc.

CZoomControl illustrates the use of zooming.

[Top]


Build

The source code for this example application can be found in the directory:

examples\Graphics

It may be in the directory in which you installed Symbian OS, or it may be in src\common\developerlibrary\. It includes the two project files needed for building: bld.inf and the .mmp file.

The Symbian OS build process describes how to build this application. For the emulator, an application called GraphicsShell.exe is created in epoc32\release\winscw\<udeb or urel>\.

[Top]


Usage

  1. Launch the emulator:

    \epoc32\release\winscw\<udeb or urel>\EPOC.EXE.

  2. Click on GRAPHICSSHELL to run the application. If using the TechView emulator, this will be in the Extras menu.

  3. The controls are listed on the menu List of Programs. Press the appropriate menu item to select a specific control.

  4. Step through each phase of the example by pressing the space bar or by tapping on the window drawn by that example.

[Top]


Class summary

By the drawing control:

By the zooming control: