×
Namespaces

Variants
Actions

How to insert an image into a skin aware CEikRichTextEditor

From Nokia Developer Wiki
Jump to: navigation, search
Article Metadata
Article
Keywords: CEikRichTextEditor
Created: lbuczkow (05 Jun 2007)
Last edited: hamishwillee (30 May 2013)
In 2006, Nokia published an example ("S60 Platform: Rich Text Editor Example v2.0") demonstrating how to insert an image into CEikRichTextEditor. However, the published solution is not skin aware: if the CEikRichTextEditor control is made skin aware the inserted pictures are drawn on white background.

The following code demonstrates how pictures can be made skin aware.

How does the solution work?

Images are inserted into the rich text control contents as CRTxPicture objects:

void
CRTx::InsertPictureL(
MRTxBackgroundDrawer & aControl,
TInt aPos,
CFbsBitmap & aBitmap,
CFbsBitmap & aBitmapMask)
{
CRTxPicture* picture;
 
picture = new(ELeave) CRTxPicture(
iTextBox->GetSystemGc(), aControl, aBitmap, aBitmapMask);
 
CleanupStack::PushL(picture);
TPictureHeader header;
header.iPicture = TSwizzle<CPicture>(picture);
 
iTextBox->RichText()->InsertL(aPos, header);
 
CleanupStack::Pop();
}

CRTxPicture is derived from CPicture and implementes Draw method in a way first the skin background is drawn, second the picture itself is drawn:

void
CRTxPicture::Draw(
CGraphicsContext & aGc,
const TPoint & aTopLeft,
const TRect & aClipRect,
MGraphicsDeviceMap * aMap) const
{
CBitmapContext& gc = static_cast<CBitmapContext &>(aGc);
TRect bmpPieceRect(TPoint(0,0),iBitmap->SizeInPixels());
 
// here is the skin background drawn
iControl.RTxDrawBackground(aTopLeft, bmpPieceRect, gc);
 
// then the picture itself
gc.BitBltMasked(aTopLeft, iBitmap, bmpPieceRect, iBitmapMask, ETrue);
}

The skin background is actually drawn in the container. For this reason the container must implement the MRTxBackgroundDrawer class.

class MRTxBackgroundDrawer
{
public:
virtual void
RTxDrawBackground(
const TPoint & aDstPos,
const TRect & aRect,
CBitmapContext & gc) = 0;
};
class CMyAppContainer : public CCoeControl, public MRTxBackgroundDrawer
void
CMyAppContainer::RTxDrawBackground(
const TPoint & aDstPos,
const TRect & aRect,
CBitmapContext & gc)
{
#ifdef USE_SKIN
MAknsSkinInstance * skin = AknsUtils::SkinInstance();
MAknsControlContext * cc AknsDrawUtils::ControlContext(this);
 
AknsDrawUtils::DrawBackground(
skin, cc, this, gc, TPoint(0, 0), aRect, KAknsDrawParamDefault);
#else
gc.SetPenStyle(CGraphicsContext::ENullPen);
gc.SetBrushColor(KRgbBlue);
gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
gc.DrawRect(aRect);
#endif
}


Notes

Add MACRO USE_SKIN to the .mmp file.

Source code

The code consists of the following files:

  • MyAppContainer.cpp - a part of the container implementation showing how to use CRTx
  • RTxBackgroundDrawer.h - an abstract class used for drawing skin background from CRTxPicture
  • RTxPicture.h, RTxPicture.cpp - a class for handling pictures in rich text editor
  • RTx.h, RTx.cpp - a helper class for easy handling rich text editor


///////////////////////////////
// MyAppContainer.cpp (parts)
///////////////////////////////
 
#include <eikclbd.h>
#include <akniconarray.h>
#include <gulicon.h>
#include <AknIconUtils.h>
#include "RTx.h"
#include <MyAppmif.mbg>
#include "MyAppDocument.h"
#include "MyAppViewDevices.h"
#include "MyAppContainer.h"
 
#ifdef USE_SKIN
#include <AknsDrawUtils.h>
#include <AknsBasicBackgroundControlContext.h>
#endif
 
#define LKMyAppMIF L"\\resource\\apps\\myapp.mif"
 
CMyAppContainer::CMyAppContainer(CMyAppViewDevices* aView) : iView(aView)
{
}
 
CMyAppContainer::~CMyAppContainer()
{
delete iRTx;
delete iTextBox;
for(int i = 0; i < iBitmap->Count(); i++)
delete iBitmap->At(i);
delete iBitmap;
for(int i = 0; i < iBitmapMask->Count(); i++)
delete iBitmapMask->At(i);
delete iBitmapMask;
#ifdef USE_SKIN
delete iBackGround;
#endif
}
 
void CMyAppContainer::LoadBitmapListL()
{
_LIT(KMyAppMif, KMyAppMIF);
PrepareBitmapL(KMyAppMif, EMbmMyAppmifImage, EMbmMyAppmifImage_mask); // the image (bitmap or svg)
}
 
void CMyAppContainer::AddSomeTextAndImageL()
{
_LIT(KText1, "Hello World!");
 
iRTx->AddTextL(KText1);
iRTx->AddCarriageReturnL();
iRTx->AddPictureL(*this, *(iBitmap->At(0)), *(iBitmapMask->At(0)));
}
 
void CMyAppContainer::ConstructL(const TRect& aRect)
{
CreateWindowL();
 
iBitmap = new (ELeave) CArrayFixFlat<CFbsBitmap *>(1);
iBitmapMask = new (ELeave) CArrayFixFlat<CFbsBitmap *>(1);
 
LoadBitmapListL();
 
iTextBox = new (ELeave) CRTxEditor(TGulBorder::ENone);
iTextBox->SetMopParent(this);
iRTx = new (ELeave) CRTx(iTextBox);
 
TInt edwinFlags = EEikEdwinInclusiveSizeFixed|EEikEdwinNoAutoSelection|EEikEdwinDisplayOnly|EEikEdwinReadOnly|
EEikEdwinLineCursor|EEikEdwinNoHorizScrolling|EEikEdwinAvkonDisableCursor;
 
iTextBox->ConstructL(this, 0, 0, edwinFlags,EGulFontControlAll, EGulAllFonts);
iTextBox->SetAknEditorFlags(edwinFlags);
 
iTextBox->SetContainerWindowL(*this);
iTextBox->SetFocus(ETrue);
 
AddSomeTextAndImageL();
 
SetRect(aRect);
#ifdef USE_SKIN
iBackGround = CAknsBasicBackgroundControlContext::NewL( KAknsIIDQsnBgAreaMain, Rect(), EFalse );
#endif
ActivateL();
}
 
void CMyAppContainer::SizeChanged()
{
TRect r = Rect();
if (iTextBox)
{
TSize scr = CEikonEnv::Static()->ScreenDevice()->SizeInPixels();
iTextBox->SetExtent(TPoint(0, 0), TSize(r.Width(), r.Height()));
}
}
 
void CMyAppContainer::HandleResourceChange(TInt aType)
{
CCoeControl::HandleResourceChange(aType);
if (aType == KEikDynamicLayoutVariantSwitch)
{
SetRect(iView->ClientRect());
}
}
 
void CMyAppContainer::Draw(const TRect& aRect) const
{
CWindowGc& gc = SystemGc();
#ifdef USE_SKIN
MAknsSkinInstance* skin = AknsUtils::SkinInstance();
MAknsControlContext* cc = AknsDrawUtils::ControlContext(this);
AknsDrawUtils::Background(skin, cc, this, gc, aRect);
#else
gc.SetPenStyle(CGraphicsContext::ENullPen);
gc.SetBrushColor(KRgbBlue);
gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
gc.DrawRect(aRect);
#endif
}
 
TInt CMyAppContainer::CountComponentControls() const
{
return 1;
}
 
CCoeControl* CMyAppContainer::ComponentControl(TInt aIndex) const
{
switch (aIndex)
{
case 0:
return iTextBox;
default:
return NULL;
}
}
 
TKeyResponse CMyAppContainer::OfferKeyEventL(const TKeyEvent& keyEvent, TEventCode type)
{
if (type != EEventKey )
return EKeyWasNotConsumed;
 
switch (keyEvent.iCode)
{
case EKeyLeftArrow:
case EKeyRightArrow:
return EKeyWasNotConsumed;
}
return iRTx->OfferKeyEventL(keyEvent, type);
}
 
// from MRTxBackgroundDrawer
void CMyAppContainer::RTxDrawBackground(const TPoint& aDstPos, const TRect& aRect, CBitmapContext& gc)
{
#ifdef USE_SKIN
MAknsSkinInstance* skin = AknsUtils::SkinInstance();
MAknsControlContext* cc = AknsDrawUtils::ControlContext(this);
AknsDrawUtils::DrawBackground(skin, cc, this, gc, TPoint(0, 0), aRect, KAknsDrawParamDefault);
#else
gc.SetPenStyle(CGraphicsContext::ENullPen);
gc.SetBrushColor(KRgbBlue);
gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
gc.DrawRect(aRect);
#endif
}
 
#ifdef USE_SKIN
TTypeUid::Ptr CMyAppContainer::MopSupplyObject(TTypeUid aId)
{
if (aId.iUid == MAknsControlContext::ETypeId && iBackGround)
return MAknsControlContext::SupplyMopObject(aId, iBackGround);
return CCoeControl::MopSupplyObject(aId);
}
#endif
 
void CMyAppContainer::PrepareBitmapL(const TDesC& aFileName, TInt aId, TInt aIdMask)
{
CFbsBitmap* bitmap, *bitmap_mask;
AknIconUtils::CreateIconL(bitmap, bitmap_mask, aFileName, aId, aIdMask);
TSize scr = CEikonEnv::Static()->ScreenDevice()->SizeInPixels();
TSize iconSize(scr.iWidth / 2, scr.iWidth / 3); // sample resizing - depends on the image
AknIconUtils::SetSize(bitmap, iconSize, EAspectRatioNotPreserved);
AknIconUtils::SetSize(bitmap_mask, iconSize, EAspectRatioNotPreserved);
iBitmap->AppendL(bitmap);
iBitmapMask->AppendL(bitmap_mask);
}
 
///////////////////////////////
// RTxBackgroundDrawer.h
///////////////////////////////
 
/* Leszek Buczkowski, Ingraal 2006 */
 
#ifndef __RTX_BACKGROUND_DRAWER_H__
#define __RTX_BACKGROUND_DRAWER_H__
 
class MRTxBackgroundDrawer
{
public:
virtual void RTxDrawBackground(const TPoint& aDstPos, const TRect& aRect, CBitmapContext& gc) = 0;
};
 
#endif
 
///////////////////////////////
// RTxPicture.h
///////////////////////////////
 
/* Leszek Buczkowski, Ingraal 2006 */
 
#ifndef __RTX_PICTURE_H__
#define __RTX_PICTURE_H__
 
#include <gdi.h>
 
class CWindowGc;
class TSize;
class CFbsBitmap;
class MRTxBackgroundDrawer;
 
class CRTxPicture : public CPicture
{
public: // no destructor - bitmap not owned
CRTxPicture(CWindowGc& gc, MRTxBackgroundDrawer& aControl, CFbsBitmap& aBitmap, CFbsBitmap& aBitmapMask);
 
public:
TBool LineBreakPossible(TUint aClass, TBool aBeforePicture, TBool aHaveSpaces) const {return EFalse;};
void Draw(CGraphicsContext& aGc, const TPoint& aTopLeft, const TRect& aClipRect, MGraphicsDeviceMap* aMap) const;
void ExternalizeL(RWriteStream& aStream) const {};
void GetOriginalSizeInTwips(TSize& aSize) const {aSize = iSizeInTwips;};
 
protected:
TSize iSizeInTwips;
MRTxBackgroundDrawer& iControl;
CFbsBitmap* iBitmap;
CFbsBitmap* iBitmapMask;
};
 
#endif
 
///////////////////////////////
// RTxPicture.cpp
///////////////////////////////
 
/* Leszek Buczkowski, Ingraal 2006 */
 
#include <fbs.h>
#include <w32std.h>
#include "RTxPicture.h"
#include "RTxBackgroundDrawer.h"
 
#ifdef USE_SKIN
#include <AknsDrawUtils.h>
#include <AknsBasicBackgroundControlContext.h>
#endif
 
CRTxPicture::CRTxPicture(CWindowGc& gc, MRTxBackgroundDrawer& aControl, CFbsBitmap& aBitmap, CFbsBitmap& aBitmapMask) : iControl(aControl), iBitmap(&aBitmap), iBitmapMask(&aBitmapMask)
{
TSize sizeInPixels = gc.Device()->SizeInPixels();
TSize sizeInTwips = gc.Device()->SizeInTwips();
TSize bitmapSizeInPixels = aBitmap.SizeInPixels();
iSizeInTwips = TSize(sizeInTwips.iWidth * bitmapSizeInPixels.iWidth / sizeInPixels.iWidth, sizeInTwips.iHeight * bitmapSizeInPixels.iHeight / sizeInPixels.iHeight);
}
 
void CRTxPicture::Draw(CGraphicsContext& aGc, const TPoint& aTopLeft, const TRect& aClipRect, MGraphicsDeviceMap* aMap) const
{
CBitmapContext& gc = static_cast<CBitmapContext &>(aGc);
TRect bmpPieceRect(TPoint(0,0),iBitmap->SizeInPixels());
 
// here is the skin background drawn
iControl.RTxDrawBackground(aTopLeft, bmpPieceRect, gc);
 
// then the picture itself
gc.BitBltMasked(aTopLeft, iBitmap, bmpPieceRect, iBitmapMask, ETrue);
}
 
///////////////////////////////
// RTx.h
///////////////////////////////
 
/* Leszek Buczkowski, Ingraal 2006 */
 
#ifndef __RTX_H__
#define __RTX_H__
 
#include <e32base.h>
#include <gdi.h>
#include <coedef.h>
#include <w32std.h>
#include <txtfrmat.h>
#include <eikrted.h>
#include <txtrich.h>
#include "RTxBackgroundDrawer.h"
 
class CWindowGc;
class CFbsBitmap;
 
// CRTxEditor is derived from CEikRichTextEditor in order to make protected GetSystemGc available
// as public (used in CRTx::InsertPictureL)
class CRTxEditor : public CEikRichTextEditor
{
public:
CRTxEditor(const TGulBorder& aBorder) { iBorder = aBorder; };
CWindowGc& GetSystemGc() const { return SystemGc(); };
};
 
class CRTx : public CBase
{
public:
CRTx(CRTxEditor* aTextBox);
~CRTx();
TKeyResponse OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType);
void AddCarriageReturnL();
void AddTextL (const TDesC& aText);
void InsertPictureL(MRTxBackgroundDrawer& aControl, TInt aPos, CFbsBitmap& aBitmap, CFbsBitmap& aBitmapMask);
void AddPictureL(MRTxBackgroundDrawer& aControl, CFbsBitmap& aBitmap, CFbsBitmap& aBitmapMask);
 
private:
CRTxEditor* iTextBox;
TCharFormatMask iCharFormatMask;
TCharFormat iCharFormat;
};
 
#endif
 
///////////////////////////////
// RTx.cpp
///////////////////////////////
 
/* Leszek Buczkowski, Ingraal 2006 */
 
#include "RTx.h"
#include "RTxPicture.h"
#include <eikrted.h>
#include <txtrich.h>
 
CRTx::CRTx(CRTxEditor* aTextBox)
{
iTextBox = aTextBox;
}
 
CRTx::~CRTx()
{
}
 
void CRTx::AddCarriageReturnL()
{
CRichText* richText = iTextBox->RichText();
richText->InsertL(richText->DocumentLength(), CEditableText::ELineBreak);
iTextBox->HandleTextChangedL();
}
 
void CRTx::AddTextL(const TDesC& aText)
{
CRichText* richText = iTextBox->RichText();
TInt documentLength = richText->DocumentLength();
richText->InsertL (documentLength, aText);
richText->ApplyCharFormatL(iCharFormat, iCharFormatMask,documentLength,aText.Length());
iTextBox->HandleTextChangedL();
}
 
void CRTx::InsertPictureL(MRTxBackgroundDrawer& aControl, TInt aPos, CFbsBitmap& aBitmap, CFbsBitmap& aBitmapMask)
{
CRTxPicture* picture;
picture = new(ELeave) CRTxPicture(iTextBox->GetSystemGc(), aControl, aBitmap, aBitmapMask);
CleanupStack::PushL(picture);
TPictureHeader header;
header.iPicture = TSwizzle<CPicture>(picture);
iTextBox->RichText()->InsertL(aPos, header);
CleanupStack::Pop();
}
 
void CRTx::AddPictureL(MRTxBackgroundDrawer& aControl, CFbsBitmap& aBitmap, CFbsBitmap& aBitmapMask)
{
CRichText* richText = iTextBox->RichText();
TInt documentLength = richText->DocumentLength();
InsertPictureL(aControl, documentLength, aBitmap, aBitmapMask);
}
 
TKeyResponse CRTx::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
{
if (aType == EEventKey)
{
if (aKeyEvent.iCode == EKeyDownArrow)
{
iTextBox->MoveCursorL (TCursorPosition::EFPageDown, EFalse);
return EKeyWasConsumed;
}
else if (aKeyEvent.iCode == EKeyUpArrow)
{
iTextBox->MoveCursorL (TCursorPosition::EFPageUp, EFalse);
return EKeyWasConsumed;
}
else
{
return iTextBox->OfferKeyEventL(aKeyEvent, aType);
}
}
return EKeyWasNotConsumed;
}
This page was last modified on 30 May 2013, at 07:34.
55 page views in the last 30 days.
×