How to draw an Icon on the IndicatorPane of Series 60
11 Feb 2006 - 11:31
Keywords :

Here is a way to show an icon on the IndicatorPane of Series 60. You can show an icone near to the battery pane or signal pane, for that you have to customise the code.

I've used a calss named CIndicatorIcon derived from CCoeControl. Now you have to create the ConstructL() should be like this:

void CIndicatorIcon::ConstructL()
        {
        iMyWindowGroup = RWindowGroup(iCoeEnv->WsSession());
        User::LeaveIfError(iMyWindowGroup.Construct((TUint32)&iMyWindowGroup));

        iMyWindowGroup.SetOrdinalPosition(0, ECoeWinPriorityAlwaysAtFront);
        iMyWindowGroup.EnableReceiptOfFocus(EFalse);

        CreateWindowL(&iMyWindowGroup);

        // by default setting the indicator icon to inactive
        SetIndicatorIconL(EIndicatorIconAppActive);

        ActivateL();
        }

In the ConstructL() I was calling another function called SetIndicatorIconL(), to set the icon:

void CIndicatorIcon::SetIndicatorIconL(TIndicatorIcon aIndicatorIconType, TBool aRedraw)
        {
        switch(aIndicatorIconType)
                {
                case EIndicatorIconEmpty:
                        iIndicator = CEikonEnv::Static()->CreateBitmapL(KSysIconFile, EMbmAvkonQgn_prop_empty);
                        iIndicatorMask = CEikonEnv::Static()->CreateBitmapL(KSysIconFile, EMbmAvkonQgn_prop_empty_mask);
                        break;

                case EIndicatorIconAppActive:
                        iIndicator = CEikonEnv::Static()->CreateBitmapL(KSysIconFile, EMbmAvkonQgn_bt_connect_on);
                        iIndicatorMask = CEikonEnv::Static()->CreateBitmapL(KSysIconFile, EMbmAvkonQgn_bt_connect_on_mask);
                        break;

                case EIndicatorIconAppInactive:
                        iIndicator = CEikonEnv::Static()->CreateBitmapL(KSysIconFile, EMbmAvkonQgn_prop_bt_audio);
                        iIndicatorMask = CEikonEnv::Static()->CreateBitmapL(KSysIconFile, EMbmAvkonQgn_prop_bt_audio_mask);
                        break;

                default:
                        break;
                }

        SetRect(TRect(TPoint(KIndicatorPosX, KIndicatorPosY),iIndicator->SizeInPixels()));
       
        // if aRedraw == ETrue just draw the canvas again.
        if(aRedraw)
                {
                DrawNow();
                }
        }

You have to over-ride Draw() from CCoeControl. The Draw function is as follows:

void CIndicatorIcon::Draw(const TRect& aRect) const
        {
        CWindowGc& gc = SystemGc();

        gc.Clear();
        gc.SetBrushStyle(CGraphicsContext::ENullBrush);
        gc.BitBltMasked(TPoint(aRect.iTl.iX, aRect.iTl.iY),
                iIndicator,
                TRect(TPoint(0, 0), iIndicator->SizeInPixels()),
                iIndicatorMask,
                ETrue);
        }

Now add these lines to the ConstructL() of your Application's AppUi class:

        iIndicatorIcon = CIndicatorIcon::NewL();
        // The next line will set the icon to draw and it'll draw to the screen.
        iIndicatorIcon->SetIndicatorIconL(CIndicatorIcon::EIndicatorIconAppInactive, ETrue);

Finally after running the application it'll look like this:

IndicatorIcon_applcation_foreground.jpg  IndicatorIcon_applcation_background.jpg
IndicatorIcon_applcation_background_taksview.jpg

You can download an example application from here.

IndicatorIconEx.zip
IndicatorIconEx.zip

Tutorial posted February 11th, 2006 by vin2ktalks

Submitted by Anonymous on Tue, 2006-02-14 13:25.

Interesting bit of code. Any idea why on 8.0a\S60_2nd_FP2 emulator if you try to close the app you get:

Thread panic CONE 8 [Environment found window server resources had not been freed] Panicked thread: INDICATORICONEX (id 54)

and if you try to switch away from the app without closing it you get:

Thread panic WSERV-INTERNAL 61 Panicked thread: Wserv (id 8)

Cheers, Michael


Submitted by zabbas (not verified) on Thu, 2006-07-06 12:00.

What happend when someone will start up full-screen application like a game? Will this icon still be visible?

Submitted by vin2ktalks (not verified) on Thu, 2006-07-06 12:19.

Yes, the icon will be visible even if someone starts up full-screen applications including games.

NB: I've only tested this option with Nokia 6600.


Submitted by Anonymous on Thu, 2006-07-13 09:39.

Honestly I tried this on couple Nokia's phones and got the same problem ;) Is there some way to get around it?

Submitted by vin2ktalks on Thu, 2006-07-13 10:47.

Can you tell me which games did you test with. In 6600 I've tested with 3D Snooker, Sky Force in those cases the icon was visible. But when I tested with Rally Pro Contest the icon was invisible.

Now come to the code, if you car cheching the CIndicatorIcon::ConstructL() function you can find the following line:

That is the line which will cause the icon visible always on top. But if you are opening some other application with more priority that ours then our icon will go to the background.

The first parameter of SetOrdinalPosition() is the priority. You can try with some higher priority if possible.

The document says:


Submitted by jp4symbian on Sat, 2007-05-19 12:47.

Hi vin2ktalks,

Have u been able to make the icon invisible when some other application(other than the one for which the icon is being setup in the context pane) is started?
And also the icon is visible again when we close that application and return to the menu.

In short, the indicator icon should be visible only when I am in Main Menu or Main screen and not inside any other application.

I tried various combinations of values in the function:
iMyWindowGroup.SetOrdinalPosition(0, ECoeWinPriorityAlwaysAtFront);

But i have not yet got the desired result.

If anyone else has found a solution to this problem, please post it here.

Thanks......


Submitted by vin2ktalks on Thu, 2007-05-24 14:22.

Hopefully you have to always monitor which process is on foreground, when ever you find that the foreground process is not Main screen you can disable the icon. I hope this tip from Forum Nokia Technical Library will be useful for you: How can I determine if a certain application is in the foreground? (TSS000058).

The UID for some processes (in 3rd Ed. phones).:

- Phone.exe : 0x100058B3
- Idle.exe : 0x101FD64C
- Menu.exe : 0x101F4CD2

--vin2ktalks


Submitted by Pawel (not verified) on Tue, 2007-01-02 18:01.

Hello there,

There seems to be a peculiar problem with drawing of floating windows in S60 v3. Would you mind checking the following link and letting me know what you think may be the cause?

http://discussion.forum.nokia.com/forum/showthread.php?t=98273


Submitted by Cryptik (not verified) on Wed, 2006-03-01 23:00.

This article is one of many great examples of why the NewLC website is so invaluable (Eric..you rock!).

BTW, I tested vin2ktalks code using SDK 2.1 for S60/7.0s. It works great except for the Cone 8 error on application close. The problem is in the SetIndicatorIconL() function. The icons used to display the indicator are created every time the SetIndicatorIconL() function is called. Since you call this function once in the AppUI() class as well as it being called in it's own ConstuctL()... this basically creates a set of icons, then reassigns the pointers to a new set...leaving the old set floating out in memory. To fix the problem, you can either allocate all of the icon sets once in the ConstuctL() and just switch pointers, or check to see if the pointers are NULL and delete them in the SetIndicatorIconL() function before the switch statement. Adding the following code to the SetIndicatorIconL() function, just above the switch statement will correct the Cone 8 error.

// check to see if we have icons allocated
if(iIcon)
{
    delete iIcon;
    iIcon = NULL;
}
if(iIconMask)
{
    delete iIconMask;
    iIconMask = NULL;
}

Way to go vin2ktalks... great article!


Submitted by vin2ktalks on Thu, 2006-03-02 02:55.

Hi Cryptik,

Thanks for your initiative towards correcting the PANIC of this sample application.

—  vin2ktalks


Submitted by Jim Cai (not verified) on Fri, 2006-03-10 04:07.

A little bug still exists, the code should be:

// check to see if we have icons allocated if(iIndicator) delete iIndicator; iIndicator = NULL; if(iIndicatorMask) delete iIndicatorMask; iIndicatorMask = NULL;


Submitted by Dario Consoli (not verified) on Thu, 2006-05-25 16:21.

Hi vin, I found your article very interesting. Is there a way to set the icon transparency?

Dario Consoli


Submitted by Villu (not verified) on Wed, 2006-08-16 12:51.

I was wondering exactly the same thing. No matter how hard I try to give the mask to the BitBltMasked, it just won't be transparent. Is there some issue with creating the window with the RWindowGroup?

Submitted by Anonymous on Fri, 2007-01-19 17:33.

The ontop window you create will clear the area, thats why your mask doesn't work.

There is an API for makeing windows transparent, and then not clear the area, but it is not supported in any current S60 phones I know of.

Don't know about UIQ based devices.


Submitted by mayankkedia on Tue, 2007-07-03 10:11.

Hi Vishal,

Your code works fine..but I see that it creates dummy application icons in the task list..for instance if u do a long press of the app launcher key on the s60 devices..it shows the list of running applications..there i can see more then one instance of my application running.

Have u observed something like this as well..?

Cheers
mayank



copyright 2003-2009 NewLC SARL