|
|
|
This guide explains the UIQ control Progress Bar (CEikProgressInfo). The Progress Bar allows the user to see the progress of an ongoing
operation, for example, loading an application or file, or playing a media file. The Progress Bar consists of a progress indicator
that grows during an increment and shrinks during a decrement. The control can
have progress text within the bar that provides updated information on how
far the operation has progressed. The text can be displayed as either a percentage
or as a fraction. The progress indicator can also consist of a series of splits,
or lines. These splits are displayed as rectangular blocks as they fill the bar.
When the control is in this mode, progress text cannot be used.
The following functionality can be used by the application developer:
Use a Progress Bar without text and with a solid progress indicator,
Use a Progress Bar without text and with a split progress indicator,
Use a Progress Bar with text showing progress text as a fraction, for example, 27/40 and a solid progress indicator,
Use a Progress Bar with text showing progress text as percentage, for example, 23% and a solid progress indicator,
Changing the width and height of the controls,
Changing the final value of the progress,
Toggling between dimmed state and normal state.
Progress Bar control graphic examples
|
See the API documentation for Progress Bar CEikProgressInfo.
Progress Bar inherits
from Bordered Control (CEikBorderedControl).
This section explains how the control is constructed, used and destroyed. Source code examples are used and explained to illustrate how the Progress Bar control is used.
Use the following #include directive:
#include <eikprogi.h>
Use the following LIBRARY directive in the project's mmp-file:
LIBRARY eikctl.lib
Resource files can be used to construct the Progress Bar. The resource
to use is defined by the PROGRESSINFO structure, defined in Eikon.rh. The structure looks
like this:
STRUCT PROGRESSINFO
{
WORD text_type=0;
WORD splits_in_block=0;
LONG finalval=10;
LONG width=206;
LONG height=16;
}
The values given in the structure definition are default values. The structure contains the following:
text_type is the type of text to use in the Progress Bar. By default, no text.
For possible values, see the TEikProgressTextType enumeration defined in
eikon.hrh,
splits_in_block, optional, the number of vertical lines to display in the Progress Bar,
finalval defines the maximum value in the Progress Bar. When the value is reached, the progress is complete,
width defines width of the Progress Bar in pixels,
height defines height of the Progress Bar in pixels. By default zero, but in this case,
the progress info control Progress Bar calculates an appropriate value.
A common way to construct controls is to specify them in the resource files and let the framework construct them from there. Specifying the controls in resource files is the preferred way of constructing controls since it allows for easier modifications compared to creating them entirely from source code.
This section covers differentways of constructing a Progress Bar.
The example below describes how to construct a Progress Bar with the view framework.
The reason the example seems to be rather complex is because it demonstrates how to construct a complete view containing a Scrollable Container and a Layout Manager. It also encapsulates the Progress Bar in a Building Block. The view supports both pen and softkey styles; support of both styles in a view is optional.
1) Declare an enumeration for the controls to be used in the view in a *.hrh file. Hrh files are files to be included both in resource files (*.rss) and C++ files:
/* Declare in *.hrh file for use both in resource and cpp */
enum TMyViewControls
{
EMyViewScrollableContainer,
EMyViewBuildingBlock,
EMyViewProgressBar,
EMyViewNumberOfControls
};
2) Declare the controls to be used in the view in your resource (*.rss) file:
/* Declare the set of Controls to be used in the view */
RESOURCE QIK_CONTROL_COLLECTION r_my_progress_bar_view_controls
{
items =
{
QIK_CONTROL
{
unique_handle = EMyViewScrollableContainer;
type = EQikCtScrollableContainer;
control = r_my_progress_bar_scroll_pane;
},
QIK_CONTROL
{
unique_handle = EMyViewProgressBar;
type = EEikCtProgInfo;
control = r_my_progress_bar;
},
QIK_CONTROL
{
unique_handle = EMyViewBuildingBlock;
type = EQikCtCaptionedTwolineBuildingBlock;
control = r_my_progress_bar_building_block;
}
};
}
3) Define the view and its contents in your resource file:
/* The view */
RESOURCE QIK_VIEW r_my_progress_bar_view
{
pages = r_my_progress_bar_viewpages;
}
/* The view page */
RESOURCE QIK_VIEW_PAGES r_my_progress_bar_viewpages
{
pages =
{
QIK_VIEW_PAGE
{
container_unique_handle = EMyViewScrollableContainer;
page_content = r_my_progress_bar_view_container_details;
}
};
}
4) Define resource for the Scrollable Container used in the view:
/* The scrollable container used in the view */
RESOURCE QIK_SCROLLABLE_CONTAINER r_my_progress_bar_scroll_pane
{
}
5) Declare contents and properties for the Scrollable Container used in the view:
/* Contents of the Scrollable Container used in the view */
RESOURCE QIK_SCROLLABLE_CONTAINER_SETTINGS r_my_progress_bar_view_container_details
{
controls =
{
QIK_CONTAINER_ITEM
{
unique_handle = EMyViewBuildingBlock;
}
};
}
6) Define the control resource struct used in the view:
/* The Progress Bar used in the view */
RESOURCE PROGRESSINFO r_my_progress_bar
{
text_type=0;
splits_in_block=0;
finalval=10;
width=206;
height=16;
}
7) Define the settings for the Building Block containing the control:
/* Settings for the EQikCtCaptionedTwolineBuildingBlock containing the Progress Bar */
RESOURCE QIK_SYSTEM_BUILDING_BLOCK r_my_progress_bar_building_block
{
content =
{
QIK_SLOT_CONTENT
{
slot_id = EQikItemSlot1;
caption = "Choose:";
},
QIK_SLOT_CONTENT
{
slot_id = EQikItemSlot2;
unique_handle = EMyViewProgressBar;
}
};
}
8) The configurations of the view:
RESOURCE QIK_VIEW_CONFIGURATIONS r_my_progress_bar_ui_configurations
{
configurations=
{
QIK_VIEW_CONFIGURATION
{
ui_config_mode = KQikSoftkeyStylePortrait;
view = r_my_progress_bar_view;
command_list = r_my_progress_bar_commands;
},
QIK_VIEW_CONFIGURATION
{
ui_config_mode = KQikPenStyleTouchPortrait;
view = r_my_progress_bar_view;
command_list = r_my_progress_bar_commands;
}
};
}
9) The command list for the view:
RESOURCE QIK_COMMAND_LIST r_my_progress_bar_commands
{
items =
{
// This command shall only be visible in debug mode because it is only
// used to find memory leaks during development of the application.
QIK_COMMAND
{
id = EEikCmdExit;
type = EQikCommandTypeScreen;
// Indicate that this command will only be visible in debug
stateFlags = EQikCmdFlagDebugOnly;
text = "Close (debug)";
}
};
}
10) The view framework constructs the view described in this example with this code:
void CMySinglePageView::ViewConstructL()
{
ViewConstructFromResourceL(R_MY_PROGRESS_BAR_UI_CONFIGURATIONS, R_MY_PROGRESS_BAR_VIEW_CONTROLS);
}
11) The result should look something like this:
The example below describes how to construct a Progress Bar from resource with your own C++ code.
The reason the example seems to be rather complex is because it demonstrates how to construct a complete view containing a Scrollable Container and a Layout Manager. It also encapsulates the Progress Bar in a Building Block.
This example uses the resource structures from the previous example. The following code creates the Progress Bar:
#include <eikprogi.h>
#include <QikRowLayoutManager.h>
#include <QikGridLayoutManager.h>
#include <QikBuildingBlock.h>
void CMySinglePageView::ViewConstructL()
{
// Give a layout manager to the view
CQikGridLayoutManager* gl = CQikGridLayoutManager::NewLC();
SetLayoutManagerL(gl);
CleanupStack::Pop(gl);
// Create a container and give it to the view
ControlProvider()->ControlInfos().AddFromResourceL(R_MY_PROGRESS_BAR_VIEW_CONTROLS);
CQikContainerBase* container = static_cast<CQikContainerBase*>(ControlProvider()->ControlConstructIfNeededL(EMyViewScrollableContainer, *this));
ASSERT(container);
Controls().AppendLC(container);
CleanupStack::Pop(container);
// Create a layout manager to be used inside the container
CQikRowLayoutManager* rowlayout = CQikRowLayoutManager::NewLC();
container->SetLayoutManagerL(rowlayout);
CleanupStack::Pop(rowlayout);
// Create the building block (containing a Progress Bar) and
// add it to the container
CQikBuildingBlock* block = CQikBuildingBlock::CreateSystemBuildingBlockL(EQikCtCaptionedTwolineBuildingBlock);
container->AddControlLC(block, EMyViewBuildingBlock);
TResourceReader blockReader;
iCoeEnv->CreateResourceReaderLC(blockReader, R_MY_PROGRESS_BAR_BUILDING_BLOCK);
block->ConstructFromResourceL(blockReader, *ControlProvider());
CleanupStack::PopAndDestroy(); //blockReader
CleanupStack::Pop(block);
}
What the code does
1) Initializes the Command Manager with an empty Command List. The controls placed in the view add their commands to the Command List when they receive focus.
2) Creates a Layout Manager for the view. The Grid Layout Manager, as default, fills the view with its only control in this example, the Scrollable Container.
3) Loads the control collection
R_MY_VIEW_CONTROLS into the Control Provider. Then the Control Provider is
asked to create the Scrollable Container.
4) Uses the MopGetObjectNoChaining function
to determine whether the control that was created really is a class of type
CQikContainerBase before it is added to the view.
5) Creates a Layout Manager to control the layout inside the container. Adds the Layout Manager to the container.
6) Constructs the Building Block containing the Progress Bar from resource R_MY_BUILDING_BLOCK. Adds the Building Block to the container.
The Progress Bar can also be created without a Building Block. In that, case replace the last section in the code above, from the "Create building block..." comment, with the following code.
Since a pointer to the control is declared here, eikprogi.h needs
to be included in the cpp-file and eikctl.lib in the mmp-file.
// Create the Progress Bar and add it into the container
TResourceReader reader;
iEikonEnv->CreateResourceReaderLC(reader, R_MY_PROGRESS_BAR);
CEikProgressInfo* progInf = new (ELeave) CEikProgressInfo();
container->AddControlLC(progInf, EMyViewProgressBar);
progInf->ConstructFromResourceL(reader);
progInf->SetUniqueHandle(EMyViewProgressBar);
CleanupStack::Pop(progInf);
CleanupStack::PopAndDestroy(); //reader
Use AddControlLC to add controls to a Scrollable Container.
Add the controls as soon as they are created. Do not push them onto the
Cleanup Stack before they are added. Do not pop them from the Cleanup Stack
until they are fully constructed. A TCleanupItem created in AddControlLC will make sure that
the control is both cleaned up and removed from the Components Array if a leave
occurs before the control is fully constructed.
The example below describes how to construct a Progress Bar solely from C++ code.
The reason the example seems to be rather complex is because it demonstrates how to construct a complete view containing a Scrollable Container and a Layout Manager.
The following source code will construct a Progress Bar:
#include <eikprogi.h>
#include <QikScrollableContainer.h>
#include <QikRowLayoutManager.h>
#include <QikGridLayoutManager.h>
#include <QikBuildingBlock.h>
void CMySinglePageView::ViewConstructL()
{
// Give a layout manager to the view
CQikGridLayoutManager* gridlayout = CQikGridLayoutManager::NewLC();
SetLayoutManagerL(gridlayout);
CleanupStack::Pop(gridlayout);
// Create a container and add it to the view
CQikScrollableContainer* container = new (ELeave) CQikScrollableContainer();
Controls().AppendLC(container);
container->ConstructL(EFalse);
CleanupStack::Pop(container);
// Create a layout manager to be used inside the container
CQikRowLayoutManager* rowlayout = CQikRowLayoutManager::NewLC();
container->SetLayoutManagerL(rowlayout);
CleanupStack::Pop(rowlayout);
// Create the Progress Bar and add it to the container
CEikProgressInfo* progInf = new (ELeave) CEikProgressInfo();
// Get a pointer to the SInfo struct within the class
CEikProgressInfo::SInfo& info = (CEikProgressInfo::SInfo&)progInf->Info();
info.iFinalValue = 100;
info.iHeight = 100;
info.iWidth = 5;
container->AddControlLC(progInf, EMyViewProgressBar);
progInf->ConstructL();
progInf->SetUniqueHandle(EMyViewProgressBar);
progInf->SetObserver(this);
CleanupStack::Pop(progInf);
}
What the code does
1) Initializes the Command Manager with an empty Command List. The controls placed in the view add their Commands to the Command List when they receive focus.
2) Creates a Layout Manager for the view. The Grid Layout Manager fills the view with its only control in this example, the Scrollable Container.
3) Instantiates a Container and adds it to the view.
4) Creates a Layout Manager and adds it to the container.
5) Creates the Progress Bar control from C++ code. Sets the view, this, to be an observer
of the Progress Bar. The view's base class, CQikViewBase, handles focus changes in its
method HandleControlEventL. For more details see the section below on how to be notified with Control Events .
The Progress Bar can be constructed from resource files in dialogs as well. To construct a dialog from resource, a valid resource definition of that dialog must exist in one of the project's resource files.
An example of a dialog resource containing the control is given below.
For more information about the dialog class and its resource structure see CEikDialog
and DIALOG in the API documentation.
1) Declare a dialog resource containing the Progress Bar control:
RESOURCE DIALOG r_my_progress_bar_dialog
{
title = "Progress info Test";
flags = EEikDialogFlagWait;
items =
{
DLG_LINE
{
type = EEikCtProgInfo;
prompt = "Progress Info";
control = PROGRESSINFO
{
text_type = 0;
splits_in_block = 0;
finalval = 10;
width = 206;
height = 16;
};
}
};
}
The resource properties inside the Control Block are the same as the ones described in the previous section.
2) Launch the dialog from the following source code. The dialog resource ID is passed as an argument:
CEikDialog* dlg = new (ELeave) CEikDialog();
dlg->ExecuteLD(R_MY_PROGRESS_BAR_DIALOG);
The function returns immediately if EEikDialogFlagWait has not
been specified in the dialog resource. If EEikDialogFlagWait is specified,
it returns when the dialog exits. The dialog framework will in both situations delete the dialog appropriately as indicated by the D suffix of the ExcecuteLD function name.
This section covers the most common functions used for interacting with the control.
When constructing the control with resource data, no reference to the control is available
in the view class. When constructing the control with code, the preferred way might be
to not save a reference to the control. In both cases, the LocateControlByUniqueHandle
function is used to get a pointer to the control, by supplying the control's unique handle.
When constructing the view and the control from code, you must explicitly set this unique handle
by calling the method SetUniqueHandle. See the code examples below.
Note that the function will return NULL if the control could not be
found. Always check the pointer before using it!
// Set the unique handle
progInf->SetUniqueHandle(EMyViewEdwin);
// Get a pointer to the Progress Bar control
CEikProgressInfo* proginf = LocateControlByUniqueHandle<CEikProgressInfo>(EMyViewProgressBar);
This example shows how to initiate and draw the Progress Bar. The method needs a TInt as a parameter.
iProgMaxValue = 10;
iProgCountValue = iProgMaxValue - 1;
iValueToShowInProg = iProgMaxValue - iProgCountValue;
progInf->SetAndDraw(iValueToShowInProg);
An example of how to increment the value of the Progress Bar:
// The variables is reused from previous example
iProgCountValue--;
iValueToShowInProg = iProgMaxValue - iProgCountValue;
progInf->IncrementAndDraw(iValueToShowInProg);
In order to be notified when the Progress Bar changes state you
must add an observer to the Progress Bar. An observer is an object of the type
MCoeControlObserver. The observer receives a function call to its function
HandleControlEventL(CCoeControl* aControl, TCoeEvent aEventType) when the
Progress Bar changes state.
The view base class, CQikViewBase, implements the MCoeControlObserver.
The HandleControlEventL function must be overloaded in the view class because
the view inherits from CQikViewBase.
The following source code example shows how to add an object as an observer and how to receive events from the Progress Bar:
void CMySinglePageView::ViewConstructL()
{
// Construction code
…
// Adding this object as an observer
proginf->SetObserver(this);
}
void CMySinglePageView::HandleControlEventL(CCoeControl* aControl, TCoeEvent aEventType)
{
// Call base class to get focus navigation right
CQikViewBase::HandleControlEventL(aControl, aEventType);
CEikProgressInfo* proginf = LocateControlByUniqueHandle<CEikProgressInfo>(EMyViewProgressBar);
if(aControl == proginf)
{
switch(aEventType)
{
case EEventStateChanged:
// The internal state of the Progress Bar was changed,
// for example, due to another item being selected.
break;
case EEventRequestExit:
break;
case EEventRequestCancel:
break;
case EEventRequestFocus:
// The Progress Bar received a pointer down event
break;
case EEventPrepareFocusTransition:
// A focus change is about to appear
break;
case EEventInteractionRefused:
// The Progress Bar is dimmed and received a
// pointer down event.
break;
default:
break;
}
}
}
The reason for calling the base class's HandleControlEventL function is
that the view base class CQikViewBase handles focus management between controls in the view.
If the Progress Bar observer is not a class which derives from CQikViewBase, focus management must be resolved by the observer itself. If a control requests
focus and does not get it from the observer, it will generate a panic in some cases if the observer does not leave.
For more details on the TCoeEvent
type, see class MCoeControlObserver in the API documentation.
Subclassing Progress Bar is not recommended.