UIQ Technology
Symbian OS Library

UIQ 3.1 SDK        UIQ developer portal

[Index] [Spacer] [Previous] [Next]



UIQ Controls - Simple Dialog


1. Introduction

This guide explains the UIQ control Simple Dialog (CQikSimpleDialog). This control presents the user with information or asks the user for information modally. It might be used to ask the user to confirm an action, to enter simple configuration details, or to update them on progress of a task.

Simple Dialogs can contain different layouts for different screenmodes. You can have one representation for portrait, and another for landscape, for example.

The Simple Dialog is suited to simple interaction - for more complex scenarios consider using CQikViewDialog instead.

A Simple Dialog

A Simple Dialog

The picture above shows a typical Simple Dialog with a title caption and containing a building block with an icon, a caption label and an edwin to capture user input.

All parameters for Simple Dialogs are loaded from resource files.


1.1 Further Reference

See the API documentation for Simple Dialog (CQikSimpleDialog).

[Top]


2. Architecture

Simple Dialog inherits from CCoeControl.

Internally it contains a buttonbar (available if no softkeys) and an iconed title block. The rest of the client area is a scrollable container available to the be filled with use- specific controls.

[Top]


3. Using the Control

This section explains how the control is constructed, used and destroyed. Source code examples are used and explained to illustrate how the Simple Dialog is used.


3.1 Includes and Identifications

Use the following #include directive:

#include <QikSimpleDialog.h>

Use the following LIBRARY directive in the project's mmp-file:

LIBRARY qikdlg.lib

Simple dialogs are not usually members of control collections.


3.2 Resource Structure

Resource files are typically used to define dialog resources. QIK_DIALOG struct, defined in Qikon.rh, is used. The struct looks like this:

STRUCT QIK_DIALOG
    {
    BYTE    version = 0;
    LONG    flags = 0;
    LTEXT   title = "";
    LLINK   icon = -1;
    STRUCT  configurations[];
    LLINK   controls = -1;
    }

The values given in the struct definition are default values. The struct contains the following:

STRUCT QIK_DIALOG_CONFIGURATION
    {
    BYTE    version = 0;
    LONG    ui_config_mode = 0;
    LLINK   container;
    LLINK   command_list = -1;
    }

The values given in the struct definition are default values. The struct contains the following:


3.3 Construction

This section describes how to construct and manipulate a Simple Dialog.

A common way to construct Simple Dialogs is to specify them in the resource files and let the framework construct them from there.

A walkthrough of the resource structures behind the example in the picture above:

3.3.1 Construction Using Data from a Resource File

1) First we declare the dialog. This is a collection one-or-more dialog-configurations. In this example, a single configuration will suffice:

RESOURCE QIK_DIALOG r_my_simple_dialog
    {
    title = "Enter some info";
    configurations =
        {
        QIK_DIALOG_CONFIGURATION
            {
            ui_config_mode = 0;
            container = r_my_simple_dialog_container;
            command_list = r_my_simple_dialog_commands;
            }
        };
    controls = r_my_simple_dialog_controls;
    }

2) List the controls we are going to use in the dialog:

RESOURCE QIK_CONTROL_COLLECTION r_my_simple_dialog_controls
    {
    items =
        {
        QIK_CONTROL
            {
            unique_handle = ESimpleDialogBB;
            type = EQikCtIconCaptionedOnelineBuildingBlock;
            control = r_my_simple_dialog_building_block;
            },
        QIK_CONTROL
            {
            unique_handle = ESimpleDialogLabel;
            type = EEikCtLabel;
            control = r_my_simple_dialog_label;
            },
        QIK_CONTROL
            {
            unique_handle = ESimpleDialogImage;
            type = EEikCtImage;
            control = r_my_simple_dialog_image;
            },
        QIK_CONTROL
            {
            unique_handle = ESimpleDialogEdwin;
            type = EEikCtEdwin;
            control = r_my_simple_dialog_edwin;
            }
        };
    }

3) List the containers; we have two, firstly the scrollable container which every dialog has, and then the building-block we are going to use inside it for this example:

RESOURCE QIK_SCROLLABLE_CONTAINER_SETTINGS r_my_simple_dialog_container
    {
    controls =
        {
        QIK_CONTAINER_ITEM
            {
            unique_handle = ESimpleDialogBB;
            }
        };
    }
    
RESOURCE QIK_SYSTEM_BUILDING_BLOCK r_my_simple_dialog_building_block
    {
    content =
        {
        QIK_SLOT_CONTENT
            {
            slot_id = EQikIconSlot1;
            unique_handle = ESimpleDialogImage;
            },
        QIK_SLOT_CONTENT
            {
            slot_id = EQikItemSlot1;
            unique_handle = ESimpleDialogLabel;
            },
        QIK_SLOT_CONTENT
            {
            slot_id = EQikItemSlot2;
            unique_handle = ESimpleDialogEdwin;
            }
        };
    }

4) A few other things need to be handled as well, like the controls themselves and the declaration of the unique_handles for instance. This can be done as shown below:

RESOURCE IMAGE r_my_simple_dialog_image
    {
    bmpfile = "z:\\Resource\\Apps\\default_app_icon.MBM";
    bmpid = 0;
    bmpmask = -1;
    }
    
RESOURCE LABEL r_my_simple_dialog_label
    {
    txt = "Please enter something:";
    }
    
RESOURCE EDWIN r_my_simple_dialog_edwin
    {
    }

and in an .hrh file:

enum TSimpleDialogControls
    {
    ESimpleDialogBB,
    ESimpleDialogImage,
    ESimpleDialogLabel,
    ESimpleDialogEdwin
    };

5) lastly, we must have the commands that we want to show:

RESOURCE QIK_COMMAND_LIST r_my_simple_dialog_commands
    {
    items=
        {
        QIK_COMMAND
         {
         id = EEikBidYes;
         type = EQikCommandTypeYes;
         text = "Yes";
         },
        QIK_COMMAND
         {
         id = EEikBidNo;
         type = EQikCommandTypeNo;
         text = "No";
         }
        };
    }

3.4 Usage

Before it can be shown, a dialog has to be prepared. The PrepareL(TInt aResourceId) method does this, and the PrepareLC(TInt aResourceId) pushes the dialog onto the cleanup stack (which is common usefulness in many code scenarios). Preparing is effectly a ConstructL for the dialog, the naming convention being borrowed from the deprecated CEikDialog.

There are two ways to launch a dialog: cause it to execute synchronously and return when closed, or execute and return immediately, it still showing, and notify you asynchronously when it closes later. These are termed waiting and non-waiting respectively.

3.4.1 Waiting

The RunL() and RunLD() methods both have versions that return a TInt to indicate the command that closed them. They wait for the dialog to be closed before returning. RunLD() also destroys the dialog (popping it from the stack, as pushed by PrepareLC).

3.4.2 Non-Waiting

The RunL() and RunLD() methods both have versions that take a TRequestStatus parameter. They return immediately, but complete that request when they are dismissed. RunLD() also destroys the dialog (popping it from the stack, as pushed by PrepareLC).

The PrepareLC(); RunLD(); is such a common combo that the ExecuteLD(); member is provided for convenience.

3.4.3 Example Code: Showing a Dialog

The code below launches a dialog and notes only what command was used to exit the dialog:

CQikSimpleDialog* dialog = new(ELeave) CQikSimpleDialog;
TInt ret = dialog->ExecuteLD(R_MY_SIMPLE_DIALOG);
if(ret == EEikBidYes)
    {
    ...

The dialog is shown and awaits for the user to dismiss it before returning to the caller with the ID of the button used to dismiss it.

3.4.4 Example Code: Examining a Control in a Dismissed Dialog

Our test resource contains a CEikEdwin which the user can use to enter some text in. We can fetch the text if we know the unique-handle of that control, as shown below:

CQikSimpleDialog* dialog = new(ELeave) CQikSimpleDialog;
dialog->PrepareLC(R_MY_SIMPLE_DIALOG);
TInt ret = dialog->RunL();
if(ret == EEikBidYes)
    {
    CEikEdwin* edwin = dialog->LocateControlByUniqueHandle<CEikEdwin>(ESimpleDialogEdwin);
    if(edwin)
        {
        ...
        }
    }
CleanupStack::PopAndDestroy(dialog);

You'll note that we need to keep the dialog around after it has been dismissed, using the RunL rather than RunLD or ExecuteLD.

3.4.5 Example Code: Closing Conditionally

In our example, it might make little sense to close the dialog without entering something in the edwin. To conditionally allow closing, we have to subclass the dialog in order to enter some code into the command handling to only close the dialog if text has been entered.

class CMyDialog: public CQikSimpleDialog
    {
public:
    void HandleCommandL(CQikCommand& aCommand);
    };
    
void CMyDialog::HandleCommandL(CQikCommand& aCommand)
    {
    if(aCommand.Id() == EEikBidYes)
        {
        const CEikEdwin* edwin = LocateControlByUniqueHandle<const CEikEdwin>(ESimpleDialogEdwin);
        if(edwin)
            {
            if(!edwin->TextLength())
                {
                _LIT(KWarning,"Please enter something!"); // i18n in real apps
                User::InfoPrint(KWarning);
                return; // don't close or anything
                }
            }
        }
    CQikSimpleDialog::HandleCommandL(aCommand); /* default behaviour is to close, returning the command id,
        if the command-type is EQikCommandTypeYes, EQikCommandTypeNo or EQikCommandTypeCancel */
    }

The dialog is launched as in section 3.4.3 above, except that you must construct a CMyDialog instance instead of the base CQikSimpleDialog one, which doesn't have this simple check.

A more developed app might observe the Edwin and disable the Yes command whenever the Edwin is empty.