buttons RAVKONSOFTKEYSOPTIONSBACK
form = r_opponentform_form;
Set the flags to indicate the following about the dialog:
• EEikDialogFlagWait— the dialog is waiting
• EEikDialogFlagNoDrag— cannot be moved
• EEikDialogFlagNoTitleBar— has no title
• EEikDialogFlagFillAppClientRect— fills the whole screen
• EEikDialogFlagCbaButtons— uses soft keys
As usual, the buttons field determines the soft keys—in this case Options and Back. The form field refers to a FORM resource.
RESOURCE FORM r_opponentform_form flags = EEikFormEditModeOnly; items =
DLG_LINE {
type = EEikCtEdwin;
prompt = NAME_TEXT;
id = EOpponentFormDIgCldEdwin;
control = EDWIN
width = KMaxNameLength;
maxlength = KMaxNameLength; };
DLG_LINE {
type = EAknCtSlider; prompt = STRENGTH_TEXT; id = EOpponentFormDIgCldSlider;
control = SLIDER {
layout = EAknFormSliderLayoutl; minvalue = 0; maxvalue = 100; step = 5;
minlabel = MIN_TEXT; maxlabel = MAX_TEXT;
valuetype = EAknSliderValuePercentage; };
DLG_LINE {
type = EAknCtPopupFieldText;
prompt = POWER_TEXT;
id = EOpponentFormDIgCldPopup;
itemflags = EEikDIgltemTakesEnterKey | EEikDIgltemOfferAIIHotKeys;
control = POPUP_FIELD_TEXT {
popupfield = POPUP_FIELD {
width = KMaxPowerLength; };
textarray = r_opponentform_power_popup_field_textarray;
As a minimum, the FORM resource should define the flags and items components. In the OpponentForm example, the flags used are:
• EEikFormEditModeOnly— indicates that the form should have an edit mode only.
• EEikFormHideEmptyFields— hides empty fields.
• EEikFormShowBitmaps— displays bitmaps in labels.
• EEikFormUseDoubleSpacedFormat— splits labels and controls onto two lines.
The items field refers to an array of dialog lines (DLG_LINE), which are the fields in the form. Each dialog line should contain a minimum of type, prompt, id and control. In the OpponentForm example, the third dialog line contains a pop-up field text control—this has the optional itemflags indicating that it should open the pop-up window when the Selection key is pressed, as shown in Figure 6-18.
Figure 6-18. Pop-up field control.
|
JH |
Opponent Farm |
|
1 1 | |
|
* 1 | |
|
Special...: |
® Invisible 1 |
|
O Magical O Plioble O Gullible Q Fallible | |
|
Ok Cancel | |
Creating a Form-Derived class
In order to use the form dialog defined in the resource file, it is necessary to derive from CAknForm and override some of its methods. In OpponentForm, the class COpponentFormForm illustrates this process.
class COpponentFormForm : public CAknForm public: // Constructor static COpponentFormForm* NewL(TOpponentFormOpponent& aOpponent);
private: // Constructor
COpponentFormForm(TOpponentFormOpponent& aOpponent) : iOpponent(aOpponent){};
On construction, it is usual to provide a reference to the data the form is to modify. In the OpponentForm example, a reference to a T-class, TOpponentFormOpponent, is passed through. This class has member data for the name, strength (defaulting to 50), and power of an opponent. A public method, lsValid(), determines whether the object contains valid data.
As with all dialogs, the form values can be initialized in PreLayoutDynlnitL(), using ControlOrNull() to obtain a handle on each control as required. In COpponentFormForm, PreLayoutDynlnitL() calls a private convenience method, LoadFormValuesFromDataL(), to perform the initialization. This is convenient, as it means LoadFormValuesFromDataL()can also be used to discard any changes if the user cancels a save.
When changes to the form data are to be saved—for example, if Save has been selected from the Options menu—the framework calls SaveFormDataL(). Therefore, this function must be overridden in the derived form class to ensure that the values in the controls are saved back into the form's member data.
TBool COpponentFormForm::SaveFormDataL() CAknSlider* slider = static_cast<CAknSlider*>(ControlOrNull(EOpponentFormDlgCldSlider)); if (slider)
¡Opponent.SetStrength(slider->Value()); return ETrue;
As usual, the ControlOrNull() method provides access to the form's controls. The data in each control can then be obtained. If all saves have been successful—for example, if valid values have been entered—then SaveFormDataLQ should return ETRue, otherwise it should return EFalse.
If the user chooses to cancel the changes made to the form—for example, when selecting No In the save query—the framework calls DoNotSaveFormDatal_() to discard any changes. Override this function in the derived form class to ensure that the values of the form's controls revert to those in the form data. This is done in the same way as when initializing the form values. In COpponentFormForm it is achieved by simply calling the private convenience method, LoadFormValuesFromDataL(), which resets the values.
Executing a Form
To construct and execute a form, use the standard dialog methods—for example, ExecuteLD(). In OpponentForm this is performed in COpponentFormContainer::NewOpponentL(), shown below, and also in COpponentFormContainer::OpenOpponentL(). The AppUi calls these functions in response to the New and Open commands, respectively.
void COpponentFormContainer::NewOpponentL() TOpponentFormOpponent opponent;
COpponentFormForm* form = COpponentFormForm::Newl_(opponent); form->ExecuteLD(R_OPPONENTFORM_FORM_DIALOG);
Previous |

Notes
Series 60 uses notes to convey information to users about a current situation. In general, a note is displayed on screen for a couple of seconds, but it can be dismissed earlier by the user.
A number of predefined notes exist, which give the functionality and appearance required by most applications. These predefined notes range from confirming actions to providing warnings to a user and are outlined in Table 6-2.
Wrapped notes and global notes offer an easy way to display simple notification messages. (However, global notes should be used sparingly as they take system focus even when the application that called them is in the background.) Wait and Progress notes are more complex and require a little more work.
Example implementations of all these note types are featured in later sections of this chapter. The applications ConfirmationNote, WaitNote, and ProgressNote are used as the basis of the discussion that follows.
Bear in mind that notes should be used sparingly to achieve maximum effect in an application. This is particularly true of the more serious error notes and warning notes—an information note should be used in preference to an error note unless something serious has happened. Please refer to the Series 60 Ul style guide, provided with the SDK documentation, for further details.
Wrapped Notes
To standardize the notifications displayed by applications and to make life easier for developers, Series 60 offers wrapped notes. These are standard notes where you just need to supply the text you want to display. It is not necessary to specify a resource—a wrapped note will already have a resource associated with it, and this will define the layout, particular image and tone sound for it to use. There are four different types of wrapped notes: Confirmation Note, Information Note, Warning Note and Error Note. Table 6-2 shows an example note of each type and describes the tone associated with each.
Table 6-2. Predefined Notes
Type of Note
Class Name
Description
Example
Confirmation CAknConfirmationNote
Informs that an action was successful (for example, a game saved successfully). A short, quiet tone may play when the note displays.
information CAkn Information Note
Informs that an error occurred which can be rectified, usually in response to user input (for example, entering a duplicate player name). A medium tone may play when the note displays.
Warning
CAknWarningNote
Informs that a situation occurred that may require user intervention (for example, reaching the maximum number of saved games for an application). A long, loud tone plays when the note displays.
Error
CAknErrorNote
Informs that a serious situation occurred, which could cause considerable problems if the user does not intervene (for example, entering an incorrect PIN, causing a lock out). A long, distinctive tone plays when the note displays.
Wait CAknWaitDialog Informs a user that
/CAknWaitNoteWrapper an event is occurring which may take some time, but gives no indication of the progress or length of the event. An animation shows while the event is occurring. Pressing the right soft key cancels the note and the processing. Otherwise, the wait -note closes when—
Progress CAknProgressDialog the processing completes.
Informs a user that an event is occurring which may take some time. The progress or length of the event is indicated by means of a progress bar, which increments at regular intervals. Pressing the right soft key cancels the note and the processing. Otherwise, the progress note closes when the-
Global
CAknGlobalNote processing completes.
Displays even if the application launching the note is not currently displayed. You can use such notes to—
Type of Class Name Note
Description Example confirmations, errors, information about the current battery state, and so on. A permanent note does not timeout or disappear when the user presses a key, and must be cancelled in code.
Custom CAknNoteDialog You can customize notes if required (for example, to display a different icon). Text can be either static (for example, "Saving Game") or variable (for example, "Delete saved game 3," where the number of games is determined at runtime). Note that the variable part may only be an integer.
CAknNoteDialog does not derive from CAknDialog and so has no menu capabilities.
The application Confirmation Note shows how to use a wrapped note. This particular example displays a confirmation note, but all wrapped notes are executed similarly. When Save Game is selected from the Options menu, the current game "saves," and, if successful, a note displays to confirm this, as shown in Figure 6-19. The code for "saving the game" is not actually implemented—an empty method, SaveGameQ is used to indicate where the saving would be performed.
Figure 6-19. Game saved confirmation note.
A wrapped note is initially created using the first-phase constructor. For a confirmation note, the class of interest is CAknConfirmationNote. Construction is then completed using ExecuteLDO, passing in a descriptor for the note to display. This function completes the second phase of construction, displays the note and destroys it on exit. In ConfirmationNote, the note is executed in the CConfirmationNoteAppUi::HandleCommandl_0 function:
HBufC* noteText;
noteText = StringLoader:: Load LC (R_S AVE D_G AM E_N OTE_TEXT); CAknConfirmationNote* note = new (ELeave) CAknConfirmationNoteO; note->ExecuteLD(*noteText); CleanupStack::PopAndDestroy(noteText);
, The construction and execution of all standard wrapped notes follows this same
TfP pattern. The only thing that differs is the name of the class itself. This name can be
CAknConfirmationNote, CAknlnformationNote, CAknWarningNote or CAknErrorNote.
Customized Notes
If you need to deviate from the standard wrapped notes—for example, to provide a custom bitmap or a different tone—you can define your own resource for the note and execute this instead. In the ConfirmationNote example, when the application is started, a customized confirmation note is displayed to indicate how many saved games have been loaded, as shown in Figure 6-20.
- Figure 6-20. Customized confirmation note.
Although this note appears similar to the wrapped note seen earlier, it has been customized to display a different bitmap icon—as defined by the following resource:
RESOURCE DIALOG r_confirmationnote_loaded_games_note flags = EAknConfirmationNoteFlags;
DLGJJNE {
type = EAknCtNote; id = EConfirmationNote;
control = AVKON_NOTE {
layout = EGeneralLayout;
singularjabel = LOADED_GAMES_SINGULAR_TEXT; pluraljabel = LOADED_GAMES_PLURAL_TEXT; imagefile = "z:\\system\data\avkon.mbm"; imageid = EMbmAvkonQgn_indi_marked_add;
imagemask = EMbmAvkonQgn_indi_marked_add_mask; };
The resource uses standard flags, which determine to some extent the type of note that displays. The EAknConfirmationNoteFlags flag is used to indicate that it is a confirmation note.
t By default, a confirmation note has no soft key labels, but it cancels if the user
TfP presses either key. To explicitly label the right soft key as Cancel you can specify the soft keys for the note to be R_AVKON_SOFTKEYS_CANCEL in the buttons field of the DIALOG resource.
The dialog should have a single line, which as usual has a type (EAknCtNote), an id, and a control (of type AVKON_NOTE).
For the AVKON_NOTE control, the following need to be defined:
• layout— This determines the note's appearance. The general layout has been specified for the Confirmation Note example, but other options can be found in avkon.hrh.
• singularjabel and pluraljabel— These set different text to be displayed for singular and plural labels. In the Confirmation Note example, the labels are set to "Loaded %d game" and "Loaded %d games", respectively. The value for the "%d" is set when the note is constructed. Note that using the StringLoader class and the SetTextLO method can produce more flexible results at runtime.
imagefile, imageid and imagemask— These determine what image the note will display. In the Confirmation Note example, the standard confirmation note icon is not displayed. For simplicity, another image from avkon.mbm was chosen, but you can define your own image. The imagefile specifies the location of the .mbm file containing the image to be displayed. The imageid is the position of the image in that file, and theimagemask is the position of the image mask in the file.
Constructing and Executing a Customized Note
To create a customized note, derive the note dialog class from CAknNoteDialog. It should be constructed using standard dialog construction and execution methods. In the Confirmation Note example, this is performed in the container's
ConstructLO method.
[View full widthl void CConfirmationNoteContainer::ConstructL(const TRect& aRect) CreateWindowLO;
CAknNoteDialog* note = new (ELeave) CAknNoteDialog(CAknNoteDialog::EConfirmationTone, * CAknNoteDialog::EShortTimeout);
note->PrepareLC(R_CONFIRMATIONNOTE_LOADED_GAMES_NOTE); Tint numberOfLoadedGames = LoadGamesO; note->SetTextPluralityL(numberOfLoadedGames > 1); note->SetTextNumberL(numberOfLoadedGames); note->Runl_DO;
SetRect(aRect); ActivateLO;
The constructor requires arguments for the tone and timeout value. As the Confirmation Note example customizes a confirmation note, it passes in EConfirmationTone for the tone and EShortTimeout for the timeout. This is essentially what the confirmation wrapper class does for you. The note can be executed by calling ExecuteLD(), passing in the DIALOG resource created in the previous step.
Alternatively, if it is required to call other methods before execution, you must call PrepareLCQ first, then call any other methods, and then call RunLDQ. In the Confirmation Note example, the dynamic element of the message label must be set, so the PrepareLC(), RunLD() route was chosen. The dynamic text for the Confirmation Note example relates to the number of games loaded. A dummy method, LoadGamesQ, has been implemented to determine this value. If more than one game has been loaded, SetTextPluralityL()is called, passing ETRue, and the pluraMabel will then be used. If only one game has been loaded, SetTextPluralityL() is called with EFalse and the singularjabel used.
Wait Notes
A wait note is used to inform the user that processing is taking place—no indication is given of the time needed to complete the processing. This subsection looks at the WaitNote example, which shows how to create a wait note. This involves defining the note in resource, constructing and executing a wait note wrapper object, and creating a MAknBackgroundProcess derived class.
In the WaitNote application, selecting Save Game from the Options menu causes a wait note to display while the game saves, as shown in Figure 6-21. If the user cancels the note, the application cancels the saving of the game. The methods for saving the game and canceling saving are not actually implemented—the dummy methods, SaveGamePartToFileQ, CompleteGameSaveQ, and CancelGameSaveQ are used to indicate where this functionality would be performed.
- Figure 6-21. Wait note.
Defining a Wait Note in Resource
A wait note is defined in a resource structure using a DIALOG in a similar way to a customized note. RESOURCE DIALOG r_waitnote_saving_game_note flags = EAknWaitNoteFlags;
DLGJJNE {
type = EAknCtNote;
id = EConfirmationNoteDlgCldSavingNote;
control = AVKON_NOTE {
layout = EWaitLayout;
singularjabel = SAVING_GAME_TEXT;
imagefile = "z:\\system\data\avkon.mbm";
imageid = EMbmAvkonQgn_note_progress;
imagemask = EMbmAvkonQgn_note_progress_mask;
animation = R_QGN_GRAF_WAIT_BAR_ANIM; };
Set the dialog flags to EAknWaitNoteFlags.
The AVKON_NOTE should have:
• layout set to EWaitLayout.
• animation field to animate the wait bar. Set this to R_QGN_GRAF_WAIT_BAR_ANIM to obtain the standard animation.
• imagefile, imageid and imagemask appropriate for a wait note. This is set to standard wait note values in the WaitNote example.
Constructing and Executing a Wait Note Wrapper Object
Wait note wrappers are constructed and executed in a different way to other dialogs. A wait note wrapper is actually a wait note wrapped up in an Active Object, so it does not behave in the same way as other dialogs. The same functionality can be achieved using the CAknWaitDialog, but this involves writing an Active Object (CActive-derived class) and is therefore slightly more complex. The progress note in the next subsection shows how this is done.
A wait note wrapper is constructed and executed using its Newl_0 and ExecuteLO methods. In the WaitNote example, this is performed in response to the user selecting Saved Game from the Options menu, in
CWaitNoteContainer::SaveGamel_(). void CWaitNoteContainer::SaveGamel_0
CAknWaitNoteWrapper* waitNoteWrapper = CAknWaitNoteWrapper::Newl_0;
// reinterpret_cast is required as CAknWaitNoteWrapper inherits privately from CActive! CleanupStack::PushL(reinterpret_cast<CBase*>(waitNoteWrapper));
if (!waitNoteWrapper->ExecuteL(R_WAITNOTE_SAVING_GAME_NOTE, *this))
CancelGameSaveO;
CleanupStack::PopAndDestroy(waitNoteWrapper);
The ExecuteLOfunction must be supplied with a DIALOG resource and a reference to a MAknBackgroundProcess object (implementation of this mixin class is discussed in the next subsection). In the WaitNote example, the container class, CWaitNoteContainer, implements MAknBackgroundProcess, so a dereferenced this pointer is passed through. ExecuteLO blocks until the processing is complete, and a TBool is returned indicating whether the processing completed (ETRue) or the user cancelled the note (EFalse). In the WaitNote example, the game save is cancelled if the method returns EFalse.
Unlike other dialogs, wait notes do not delete when they finish executing; they must be deleted explicitly. In the WaitNote example, the note is a local variable, so deletion is achieved through the call to CleanupStack::PopAndDestroyO-
, If the note wrapper is not member data of a class, use a reinterpret cast to cast it to
TfP a CBase pointer in order to place it onto thdDleanupStack. It cannot be placed directly onto the CleanupStack, as \tpnvately inherits fromCActive, which means that it has no (implicit) public converter to CBase*!
Creating an MAknBackgroundProcess-Derived class
A class that implements MAknBackgroundProcess is required in order to be able to instantiate the wrapper. In the WaitNote example, the container class does this job.
class CWaitNoteContainer: public CCoeControl, public MAknBackgroundProcess private: //from MAknBackgroundProcess void DialogDismissedL(Tlnt /*aButtonld*/); TBool IsProcessDoneO const; void ProcessFinishedO; void StepLQ;
MAknBackgroundProcess encapsulates the processing that occurs while the wait note displays. In WaitNote, the processing performed is the saving of the game—the wait note wrapper encapsulates an Active Object, which calls the methods in MAknBackgroundProcess as it runs.
The processing should occur in a number of small steps. In the WaitNote example, the saving of the game is split into steps, which execute in the SaveGamePartToFileO method (this is a dummy method and nothing is actually saved to a file). The number of steps completed so far is indicated by iStepsCompleted. Active Objects are covered in more detail in Chapter 3.
CAknWaitNoteWrapper is an Active Object, and so calling ExecuteLO results in a service request being made to the Active Scheduler. When the request has been serviced, MAknBackgroundProcess::lsProcessDone() is called to determine whether all of the steps of the processing have been carried out. If they have not, EFalse will be returned and MAknBackgroundProcess::Stepl_0 Will be called, causing the next step of the processing to be carried out.
If the processing is allowed to complete—that is, the user does not cancel the dialog—the framework calls
MAknBackgroundProcess::ProcessFinishedO and then MAknBackgroundProcess::DialogDismissedl_(). if the user does end the processing, DialogDismissedLO is called first by the framework. It then calls IsProcessDoneO to check whether the processing has finished, followed by ProcessFinishedO-
The method to determine whether processing is complete is IsProcessDoneO-
TBool CWaitNoteContainer::lsProcessDoneO const return (iStepsCompleted == KNumberOfStepsToSaveGame);
If the processing is complete, Etrue is returned, and EFalse if not. In the WaitNote example, this means checking that all the required steps in the procedure have been carried out, and if so, returning Etrue. In a real application, this would mean implementing some kind of state machine, or at the very least using a member flag to indicate when processing is complete.
The StepLO method is where small steps of the processing should be completed.
void CWaitNoteContainer::Stepl_0
SaveGamePartToFileO; iStepsCompleted++;
In the WaitNote example, the SaveGamePartToFileO dummy method simply wastes some time using an RTimer object.
t The StepLO method executes synchronously. It should therefore process
TfP quickly—otherwise it will not be possible to cancel the note. The thread will block, and there will be a large delay in displaying the note, as it does not display until one step completes.
Use the ProcessFinishedO or the DialogDismissedLO methods to do any postprocessing work required, such as closing files, resetting state machines, and the like.
void CWaitNoteContainer:ProcessFinishedO
CompleteGameSaveO; iStepsCompleted = 0;
In the WaitNote example, the implementation of ProcessFinishedOjust calls a dummy method to complete the game save and to reset the steps completed counter.
Progress Notes
Progress Notes are similar to wait notes, but they give the user a visual indication of what portion of the processing is still left to do. In this subsection, the application ProgressNote is used to demonstrate the techniques you should use to create a progress note. The basic steps are as follows:
1. Declare the progress note.
2. Create the progress note for a variable-length process.
3. Execute the progress note.
4. Update the progress note as a process executes.
5. Handle user cancels and completion of the progress note.
In ProgressNote, selecting Save Game from the Options menu displays a progress note while the game saves, as shown in Figure 6-22. If the user cancels the note, the application cancels the game saving. The functions to save the game and cancel saving have not been fully implemented—the dummy methods SaveGamePartToFileO, CompleteGameSaveO, and CancelGameSaveO are used to indicate where this functionality would be performed.
Figure 6-22. Progress note.
Post a comment