Header Sep
Symbian Tips, Tricks & Code
My Rating Score
Login to rate page
January 2005
Using the Jog dial from a Symbian OS C++ application
 

[Back]

Sony Ericsson's Symbian OS based smartphones all feature the versatile Jog dial controller. The UIQ User Interface makes extensive use of this for navigation and scrolling as do some of UIQ's built-in controls. We recommend that you permit users of your application the same benefits of the Jog dial controller throughout your application.

Note that the Jog dial's forward and backward events should only be captured by your application when it's running in full screen mode, since using these events in flip-closed mode breaks the UI paradigm and may be confusing for the user. If the device has the flip open and the application is using the entire screen, the full range of Jog dial events can be used.

Left and right Jog dial events will normally not be sent to your application. These key events will normally be consumed by the device before the application can detect them and will usually cause an application switch. However, you can prevent the UIQ user interace from responding to the Jog dial events and make them available to your application by calling the CaptureKeyUpAndDowns() and CaptureKey() methods in the RWindowGroup class.

The keys must be released by calling RWindowGroup::CancelCaptureKey() or RWindowGroup::CancelCaptureKeyUpAndDowns() when your application no longer requires these events.

The following code fragments illustrate how to capture Jog dial events. Since the RWindowGroup class is used, the header files "quartzkeys.h" and "w32std.h" must be included by your C++ source code files and the application must be linked with "ws32.lib".

In the following example the AppUi class is called "CExampleAppUi". The CExampleAppUi class should contain the following members:

 TInt32 iHandleJogDialKeyLeft;
 TInt32 iHandleJogDialKeyUpDownLeft;
 TInt32 iHandleJogDialKeyRight;
 TInt32 iHandleJogDialKeyUpDownRight;

To capture the key events corresponding to the use of the jog dial when the application starts, we've included the following lines in our AppUi classes ConstructL(...) member function:

void CExampleAppUi::ConstructL()
    {
    RWindowGroup windowGroup = iEikonEnv->RootWin();
    iHandleJogDialKeyLeft = windowGroup.CaptureKey(EKeyDevice3, 0, 0);
    iHandleJogDialKeyUpDownLeft = windowGroup.CaptureKeyUpAndDowns(EStdKeyDevice3, 0, 0);
    iHandleJogDialKeyRight = windowGroup.CaptureKey(EKeyDevice9, 0, 0);
    iHandleJogDialKeyUpDownRight = windowGroup.CaptureKeyUpAndDowns(EStdKeyDevice9, 0, 0);
    }

To release the keys for normal use when our application shuts down, we include the following lines in our AppUi classes destructor:

CExampleAppUi::~CExampleAppUi()
    {
    RWindowGroup windowGroup = iEikonEnv->RootWin();
    if (iHandleJogDialKeyLeft > 0)
    windowGroup.CancelCaptureKey(iHandleJogDialKeyLeft);
 
    if(iHandleJogDialKeyUpDownLeft > 0)
        windowGroup.CancelCaptureKeyUpAndDowns(iHandleJogDialKeyUpDownLeft);

     if(iHandleJogDialKeyRight > 0)
        windowGroup.CancelCaptureKey(iHandleJogDialKeyRight);
 
    if (iHandleJogDialKeyUpDownRight > 0)
        windowGroup.CancelCaptureKeyUpAndDowns(iHandleJogDialKeyUpDownRight);
    }

In order for the jog dial to return to its normal functions when your application is in the background, you need to switch key capture ON and OFF when switching to the background or foreground. You can do this by making your AppUi class implement the virtual function CCoeAppUi::HandleForegroundEventL() and the following example code shows how you might do this:

void CExampleAppUi::HandleForegroundEventL(TBool aForeground)
    {
    RWindowGroup windowGroup = iEikonEnv->RootWin();
    if (aForeground == EFalse) // going to background
        {
        if (iHandleJogDialKeyLeft > 0)
            {
            windowGroup.CancelCaptureKey(iHandleJogDialKeyLeft);
            iHandleJogDialKeyLeft = 0;
            }

        if(iHandleJogDialKeyUpDownLeft > 0)
            {
            windowGroup.CancelCaptureKeyUpAndDowns(iHandleJogDialKeyUpDownLeft);
            iHandleJogDialKeyUpDownLeft = 0;
            }

        if (iHandleJogDialKeyRight > 0)
            {
            windowGroup.CancelCaptureKey(iHandleJogDialKeyRight);
            iHandleJogDialKeyRight = 0;
            }

        if(iHandleJogDialKeyUpDownRight > 0)
            {
            windowGroup.CancelCaptureKeyUpAndDowns(iHandleJogDialKeyUpDownRight);
            iHandleJogDialKeyUpDownRight = 0;
            }
        }
    else // going to foreground
        {
        if(iHandleJogDialKeyLeft <= 0)
            iHandleJogDialKeyLeft = windowGroup.CaptureKey(EKeyDevice3, 0, 0);

        if (iHandleJogDialKeyUpDownLeft <= 0)
            iHandleJogDialKeyUpDownLeft =
                   windowGroup.CaptureKeyUpAndDowns(EStdKeyDevice3, 0, 0);

        if (iHandleJogDialKeyRight <= 0)
            iHandleJogDialKeyRight = windowGroup.CaptureKey(EKeyDevice9, 0, 0);

        if (iHandleJogDialKeyUpDownRight <= 0)
            iHandleJogDialKeyUpDownRight =
                   windowGroup.CaptureKeyUpAndDowns(EStdKeyDevice9, 0, 0);
        }
    CEikAppUi::HandleForegroundEventL(aForeground);
    }

Finally, your application needs to capture the events and handle them appropriately. You can do this by implementing CCoeAppUi::HandleKeyEventL() in your applications AppUi class like this:

TKeyResponse CExampleAppUi::HandleKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType)
    {
    if (aType != EEventKey)
        {
        return EKeyWasNotConsumed;
        }
    switch (aKeyEvent.iCode)
        {
        case EQuartzKeyFourWayUp:
        case EQuartzKeyTwoWayUp:
            {
            iEikonEnv->InfoMsg(_L("EQuartzKeyTwoWayUp"));
            return EKeyWasConsumed;
            break;
            }
        case EQuartzKeyFourWayDown:
        case EQuartzKeyTwoWayDown:
            {
            iEikonEnv->InfoMsg(_L("EQuartzKeyTwoWayDown"));
            return EKey WasConsumed;
            break;
            }

        case EKeyDevice3:
        case EQuartzKeyFourWayLeft:
            {
            iEikonEnv->InfoMsg(_L("EQuartzKeyFourWayLeft"));
            return EKeyWasConsumed;
            break;
            }

        case EKeyDevice9:
        case EQuartzKeyFourWayRight:
            {
            iEikonEnv- >InfoMsg(_L("EQuartzKeyFourWayRight"));
            return EKeyWasConsumed;
            break;
            }

        case EQuartzKeyConfirm:
            {
            iEikonEnv->InfoMsg(_L("EQuartzKeyConfirm"));
            return EKeyWasConsumed;
            break;
            }
        }
        return EKeyWasNotConsumed;
    }

There's a further discussion of how and when to use the jog dial on the Sony Ericsson Developer World Symbian OS discussion forum (see thread here>>) You can also visit http://www.yipton.net/ and look at the source code for EMame. This is a Symbian OS port of the MAME arcade game emulator that makes use of the Jog dial controller.

 

My Rating Score
Login to rate page