Friday, April 18, 2008

How to use mobile theme skin as a background for our application.

1. Enable skins support in our application by calling apps AppUi base constructor:

void CMyAppUi::ConstructL()
{
BaseConstructL(EAknEnableSkin);
...
}


2. We will require a specific context to hold the skin bitmap for your control.

CAknsBasicBackgroundControlContext* iBgContext;

3. Initialise context to a reference of the background bitmap:

void CMyAppView::ConstructL()
{
...
iBgContext = CAknsBasicBackgroundControlContext::NewL( KAknsIIDQsnBgAreaMain,aRect,ETrue);
...
}


4. Don't forget to call the context destructor:

void CSkinDemoAppView::~CSkinDemoAppView()
{
...
delete iBgContext;
...
}


5. As we are ready with a context that has the backgoround that we want to use in all controls. This is done throgh MOP relationship and we need to override the MopSupplyObject():

TTypeUid::Ptr CMyAppView::MopSupplyObject(TTypeUid aId)
{
if (iBgContext )
{
return MAknsControlContext::SupplyMopObject( aId, iBgContext );
}
return CCoeControl::MopSupplyObject(aId);
}


6. Each control Draw now be updated to display the skin as background:

void CMyAppView::Draw(const TRect& aRect) const
{
// Get the standard graphics context
CWindowGc& gc = SystemGc();

// Redraw the background using the default skin
MAknsSkinInstance* skin = AknsUtils::SkinInstance();
MAknsControlContext* cc = AknsDrawUtils::ControlContext( this );
AknsDrawUtils::Background( skin, cc, this, gc, aRect );

...
}


and

void CMyAppView::SizeChanged()
{
if(iBgContext)
{
iBgContext->SetRect(Rect());
if ( &Window() )
{
iBgContext->SetParentPos( PositionRelativeToScreen() );
}
}
}


7. Now we are ready so if we have to use it in a list box then we can use as below.
ListBox->ItemDrawer()->ColumnData()->SetSkinEnabledL(ETrue)

Header Files: AknsDrawUtils.h, AknsBasicBackgroundControlContext.h
Lib Files: aknskins.lib aknskinsrv.lib

note:
1. Nokia has introduced skin support only in S60 v2.
2. Unfortunately, the Skin API is not very well documented and may not be compatible in S60 3rd Edition

Friday, April 04, 2008

Nokia OS [NOS / ISA]

Nokia OS (NOS) is an informal name for the operating system in many Nokia mobile phones. These are informal names, there is no such product or trademark. Officially it is referred as ISA platform. It is a proprietary platform only for Nokia's internal use, it is not licensed to anyone. No direct API is provided either, but most ISA phones can be programmed with J2ME. It is sometimes called the "domestic OS"..

ISA powers Nokia Series 40 and Series 30 mobile phones.
Obtaining UID of a calling application.

The Call Application UID is 0x10005883.

you can find in the following way :
1) Firstly retrieve window id of Call Application.
2) Then passe this Window id to CApaWindowGroupName::FindByAppUid function which returns the UID.
How to start a application in a specific orientation

By default, applications are started in the current orientation of the device screen. In order to force an application to be started in landscape mode or portrait mode, a corresponding flag needs to be passed to the BaseConstructL() function in AknAppUi::ConstructL():

void CMyAppUi::ConstructL()
{
BaseConstructL( EAknEnableSkin | EAppOrientationLandscape ); // start in landscape mode
//BaseConstructL( EAknEnableSkin | EAppOrientationPortrait ); // start in Portrait mode
...
}



Note: enums Passed BaseConstructL() are different from enums that are passed to SetOrientationL().
How to change screen orientation of UI application

void CMyClass::RotateMe()
{

// Change the screen orientation.
if (CAknAppUi::EAppUiOrientationPortrait != AppUi()->Orientation())
{
AppUi()->SetOrientationL(CAknAppUi::EAppUiOrientationPortrait);
}
else
{
AppUi()->SetOrientationL(CAknAppUi::EAppUiOrientationLandscape);
}
}
How to handle Foreground / Background events

The application framework calls CCoeAppUI::HandleForegroundEventL() when the application is switched to the foreground or background. While the default implementation of this method is empty, it can be, for example, used to display messages or pause a game when a focus change event occurs.

Example:

void CMyViewAppUi::HandleForegroundEventL(TBool aForeground)
{
if (aForeground==TRUE)
{
iEikonEnv->InfoMsg(_L("Foreground true"));
}
else
{
iEikonEnv->InfoMsg(_L("Foreground false"));
}
}


Note: The aForeground parameter is true if the application is switched to the foreground (is visible) and false if the application has gone to the background.
How to handle Layout change events

Layout change events are generated when the screen size or layout is changed. The S60 platform supports multiple screen resolutions[also called as "Scalable UI"]. Thus, layout awareness is particularly crucial for those applications to reorganize the position as required. Applications can detect the changes in layout with, for example, the following methods:

1. Controls can override the CCoeControl::HandleResourceChange() to detect the KEikDynamicLayoutVariantSwitch message.
The following example code for HandleResourceChange():

    void CMyControl::HandleResourceChange(TInt aType)
{
CCoeControl::HandleResourceChange(aType); //call base class implementation
if ( aType==KEikDynamicLayoutVariantSwitch )
{
TRect rect;
// ask where container's rectangle should be
// EMainPane equals to area returned by
//CEikAppUi::ClientRect()
AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EMainPane,rect);
SetRect(rect);
}
}


2. UI controllers can override the CEikAppUi::HandleResourceChangeL() to detect the KEikDynamicLayoutVariantSwitch message.

The following example code for HandleResourceChangeL():

    void CExampleAppUi::HandleResourceChangeL(TInt aType)
{
CAknAppUi::HandleResourceChangeL( aType );
if ( aType == KEikDynamicLayoutVariantSwitch )
{
// do the re-layout of the components
}
// Controls derived from CCoeControl, handled in a
// container class
iExampleControlContainer->HandleResourceChange( aType );
//Must not call this if the components are on the control stack
//iView->HandleResourceChangeL( aType );
}

S60 View based UI application architecture


The S60 view architecture only allows one view to be active in each application. If a new view is switched to within an application, the current view is immediately deactivated.


S60 platform applications that follow the S60 view architecture require:

1. A UI controller derived from CAknViewAppUi
Responsibilities are
a) It creates one or more CAknView-derived view controllers.
b) It handles events that are not handled by the view controllers.
c) To switch between views, it activates and deactivates views.
d) It handles menu commands passed to it by the view controllers.
e) It receives events such as layout and foreground notifications from the run-time environment.

2. A view controller derived from CAknView
Responsibilities are
a) It creates one of more CCoeControl-derived views.
b) It handles registering controls for key event handling.
c) It handles menu commands.

3. 1 or more views derived from CCoeControl
Responsibilities are
a) Shows application data and state on the screen.

As this architecture allows one view to be active in each application, so it is not appropriate in the following cases:

1. Applications with any view that cannot cleanly handle unexpected activation of another view in that application.
2. Applications that provide views that can be nested over other applications, [except where embedding is used.]
3. Applications that provide controls that can be used inside other applications (for example, using a Web control inside an e-mail viewer to show an e-mail with HTML content).

Traditional Symbian OS UI application architecture


The traditional Symbian OS UI application architecture provides the most flexible approach to application UI construction. Traditional architecture is easier to port across different platforms. Traditional architecture is also the best choice for single-view applications, if launching the view from external applications is not required.


S60 platform applications that follow the traditional Symbian OS UI application architecture require:

1. A UI controller derived from CAknAppUi
Responsibilities are
a. It creates one or more CCoeControl-derived views.
b. It handles events, including enabling views to handle key events.
c. To switch between views, it creates and destroys or shows and hides views.
d. It handles menu commands.
e. It receives events such as layout and foreground notifications from the run-time environment.
2. 1 or more views derived from CCoeControl
Responsibilities are
a. Shows application data and state on the screen.
b. Receives user input.
c. Notifies the CAknAppUi-derived class of relevant events.
d. Often observes model changes (directly or via the UI controller) and updates the screen accordingly.
UI Controller in S60

UI controller is an object derived from either CAknAppUi or CAknViewAppUi, depending on your UI architecture. The UI controller is part of the controller structure in the Model - View - Controller (MVC) design pattern used to design the architecture of many GUI-based mobile applications.

Examples of services and responsibilities provided by the UI controller are as follows:

1. control stack for event handling
2. construction of views for applications
3. the top-level window owning control of the application

The UI controller is implemented in one of the following classes:

1. In a traditional architecture application architecture, the UI controller must be derived from CAknAppUi.
2. In S60 View application architecture, the UI controller must be derived from CAknViewAppUi.
3. In dialog architecture, the UI controller is typically derived from CAknAppUi

Thursday, April 03, 2008

3 things you must have in mind while making your application scalable.

If your application is scala then you allow your application to support the different display sizes, resolutions, and layouts for different S60 devices.

1. Layout information should not be hard-coded.
The S60 platform provides the AknLayoutUtils class for building layouts from resource files.
Note: that you need to override CCoeControl::HandleResourceChange and CEikAppUi::HandleResourceChangeL in your application to draw your application again in the event that the orientation of the display changes.
2. Scalable fonts should be used.
The S60 platform provides methods in the AknLayoutUtils for using logical fonts from an enumeration in the avkon.hrh file.
3. Scalable icons should be used.
Scalable icons are based on SVG Tiny (SVG-T) format graphics.
10 things you must remember when doing internationalization of your application:

1. Keep code and content separate.
2. Use Locales.
3. In UI component design, allow for text expansion.
4. Do not concatenate. [Localizing concatenated strings is difficult or impossible.]
5. Do not reuse strings. [The context, meaning, or the space available may change, making localization difficult.]
6. Use re-orderable parameters in strings.
7. Do not use text in graphics. [It all needs to be localizable.]
8. Comment the text strings.
9. Use common components
* Use AVKON component library wherever possible.
* Use StringLoader.h for re-orderable parameters.
* Use CharConv for inbound and outbound character conversions.
* CharConv contains conversion tables for all supported S60 languages and most common encodings.
* Use locale for sorting.
* Use AVKON time and date formatter strings for time/date formatting, or if you need to have new formats, use locale formatters.
10. Follow the formats / templates provided by symbian.
What is Data Caging in Symbian V9.x?

Data caging means that different applications are allowed to access only particular data areas. This prevents applications from accessing the private data of other applications.

The following list describes where different file types are stored on a mobile device:

1. The \sys\bin folder contains all binaries. This is the only folder from where an application can be launched.
Note: An application cannot read (or write) anything under the \sys\ folder without AllFiles (or TCB) capability.

2. The private (\private\) folder includes folders for all applications. The \ subfolders are application-specific and applications can access only their own folders. An application with AllFiles capability can access all private directories. The directory name under \private is determined by the SecureId (SID) of the application. If an SID is not specified, the UID3 provided in the mmp file is used.

3. The resource folder (\resource\apps\) is used for resource files of applications. This data can be icons, bitmaps, and other material useful for all the applications. Read access is allowed by all applications, write access only by processes with the AllFiles capability.

Note: So if you want to shared File / databse for both read and write between applications or between 2 exes of same application, then use a folder in c:\data\
What are @publishedAll APIs and How to find out which is @publishedAll API or not.

These Group/set of symbian APIs can be used by a 3rd party developer to futre proof his application. That means these APIs will be changed in feature versions of the SDK. So @publishedAll APIs are binary and source compatible across OS releases

By checking the .h files for the API a developer can find out if the API is @publishedAll or not.

Other tags included in Symbian headers are.
01) @internalTechnology
02) @internalComponent
03) @internalAll
04) @publishedPartner
05) @publishedAll
06) @prototype
07) @interim (a deprecated synonym of @prototype)
08) @released
09) @deprecated
10) @removed
11) @test
How To: Remove an installed application from the WINS Emulator?

All applications on symbian os emulator must reside in
[EPOCROOT]\epoc32\release\wins\udeb\z\system\apps\
or
[EPOCROOT]\epoc32\release\wins\urel\z\system\apps\
or
[EPOCROOT]\epoc32\wins\c\system\apps\

just delete the dir of the application you want.

Note: only applicable to pre-Symbian v9
How To: display global notes (independent of the focused view)

CAknGlobalNote* iGlobalNote = CAknGlobalNote::NewL();
CleanupStack::PushL( iGlobalNote );
iGlobalNote->ShowNoteL(EAknGlobalConfirmationNote, _L(”Screenshot taken!”));
CleanupStack::PopAndDestroy();
How To: make asynchronous functions synchronous?

Simply add WaitForRequest() and remove SetActive();

Example:
TRequestStatus iStat = KRequestPending;
iEncoder->Convert(&iStat, *iImage, iJpgImageData);
User::WaitForRequest(iStat); //Remove SetActive();
How To: avoid repetitive key events when pressing a key?

Use TEventCode to only capture EEventKeyDown:

TKeyResponse CAppUi::HandleKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType)
{
if((aKeyEvent.iScanCode == ‘*’)&& aType == EEventKeyDown)
{
iMenuView->HandleCommandL(ECommand);
return EKeyWasConsumed;
}
else
return EKeyWasNotConsumed;
}
How To: Externalizing and internalizing descriptors

Example:
TBuf KMaxFileNameLength iFileName
void TSettings Settings::ExternalizeL(RWriteStream& aStream) const
{
aStream << iFileName;
}

void TSettings::InternalizeL(RReadStream& aStream)
{
aStream >> iFileName;
}
In which files are UIDs used? (In Symbian v9.x)

a. in xxxApplication.cpp file static const TUid KUidXXXApp = {0xXXXXXXXX};
b. in .pkg file Header #{”XXX”},(0xXXXXXXXX),1,0,0
“..\sis\backup_registration.xml” -”!:\private\xxxxxxxx\backup_registration.xml”
private directory
c. in resource file xxx_reg-rss UID3 0xXXXXXXXX
d. when sending application to the background (HandleCommandL)
e. in paths to private directory
f. In project/properties!
stats counter