The purpose of the Hierarchical Lists API is to provide client applications means for presenting a view into their hierarchical data structures consisting of text and graphics.
Hierarchical Lists API is a library API that provides an interface to the hierarchical list UI components implemented in the Hierarchical Lists library. The API is targeted for end user applications that want to present their data structures for the user in a hierarchical list format.
Hierarchical List is a list that can display list items in a hierarchical structure. The hierarchical list items are divided into leaves and nodes. Nodes are item types that form the hierarchy in the list. They can contain other list items, including other nodes, and can be expanded and collapsed to display or hide their content. Leaves are list item types, that cannot contain any other items.
The client applications can use the API for creating local hierarchical list instances, populating the list instances with list items, modifying list content and structure, and displaying the list for the user. The list client is responsible for mediating key and pen events to the list, so that the user may interact with the list. The client is also responsible for reacting to the user actions.
The Hierarchical Lists library contains implementations for two different hierarchical list type: Single style hierarchical list and single column style hierarchical list.
Single style hierarchical list
Single style hierarchical list is a basic hierarchical list UI component that can contain items consisting of single line of text, one icon, and two optional icons. The items are one of the following two types:
a file in the directory listing. The leaf item has a default icon representing the generic document.
a folder in the directory listing. The node item uses default icons that represent expanded and collapsed folders.
By default, the items in a single style tree list are indented according to their hierarchy and, tree structure lines are drawn to emphasize the hierarchical structure and to show the relations between list items. These properties can be turned off when necessary. [Hierarchical_Lists_API_Specification.topic2_fig1 Figure 1] below shows an example of a single style hierarchical list. Theclass contains an implementation for this hierarchical list type.
Single column style hierarchical list
The name for single column style hierarchical list comes form the fact that one of its item types can display text in several columns. Opposite to the single style hierarchical list, the single column style hierarchical list provides support for marking, but does not allow the indention of list item according to the hierarchy. Single column style hierarchical list contains items of three different types:
line of text, one leaf icon, and one optional indicator icon. No default icons is set for simple data row.
of text that is divided up to three columns, one leaf icon, and two optional indicator icons. The number of available columns depends on the used layout; the third column is usable only in landscape orientation. No default icons is set for core data row.
data row, but can have separate node icons for expanded and collapsed state. By default, the subtitle row uses the expanded and collapsed folder icons. [Hierarchical_Lists_API_Specification.topic2_fig2 Figure 2] below shows an example of single column style hierarchical list. The core data row at the bottom of the list is set to have three different text column, but the third column is displayed only in landscape orientation. Note also that, due to the lack of indention and tree structure lines, the hierarchical structure is not apparent from the list, and hence, the number of levels in the list should be restricted to two. Theclass contains an implementation for this hierarchical list type.
Use cases of Hierarchical Lists API are illustrated in [Hierarchical_Lists_API_Specification.topic2.1_fig3 Figure 3].
The above figure contains the following use cases:
whole list, or
[Hierarchical_Lists_API_Specification.topic2.2_fig4 Figure 4] depicts the classes used in Hierarchical Lists API. The client application may use either theclass for single style tree list, or the class for single column style tree list. Declarations for these classes can be found in the aknsinglestyletreelist.h and aknsinglecolumnstyletreelist.h files respectively.
Both of the list classes are derived from the abstractclass, which contains the common methods for all hierarchical list types. The base class declaration is located in the akntreelist.h file.
Theinterface, declared in the akntreelistobserver.h file, is used in notifying the list observers of the changes in the list state. In order to receive these events from the list, the client application has to provide a realization of the interface and register it to the list. Several observers can be registered to the list, and each of these receives the same events.
As the list is derived from theclass, the interface can be used for observing the state changes in the list as well, but the interface provides more detailed events.
Optionally, the client may provide an implementation for theinterface, declared in the akncustomtreeordering.h file. When such implementation is set for the list, it is used to determine the ordering between the list items within each tree node. By default, the items in either of the list types are not ordered, and they remain in the order in which they were added to the nodes.
To use Hierarchical Lists API, the application has to link the Hierarchical Lists library to itself.
In general, using the API contains the following steps:
To use the hierarchical list UI component, the client application must first link itself to the Hierarchical Lists library, which contains the implementations for different hierarchical list types. The list usage is started by creating an instance of chosen list class with one of its static constructors. The construction may vary depending on the used list. However, the list cannot be constructed from resources.
The list instance is usually constructed as a component control of some application specific container class derived from theclass. This is not mandatory for list usage, but the list can be created as non-window-owning only by giving the parent control as parameter to the list constructor. If the container is not given to the list constructor, then the list creates new window for itself. The window can be later changed with the method.
Note: When the window is constructed as window-owning,, the client must set theparent for the list with the method. When the list is constructed as non-window-owning control, the given container is set as the object provider parent for the list.
After the list has been constructed, the client can change some of the list properties, populate the list, and set it ready to be drawn.
The following properties can be set with themethod:
that the focus jumps from the bottom of the list to the top when scrolling downwards and from the top to bottom when scrolling upwards.
that are used to depict the hierarchical structure of the list.
for list items. The marquee scrolling is used when the text of the focused item does not fully fit to the screen.
list items according to the list hierarchy. When indention is disabled, the tree structure lines cannot be drawn, as there is no space in front of the list items.
the list can always be marked by the client application through the API, but when the list is set markable, the list responds also to user actions by marking the items on defined key and pen events. Note that not all of these flags are applicable to every list type and some of the flags may be set permanently on for some list types. The applicable flags for each list type are specified in their header files. None of the flags is by default set, unless it is permanently set for the list type.
In addition to these flags, theclass contains the method that changes the expand and collapse indicators that are superimposed over the icon of each non-empty node. In default mode, the function indicator icons represent arrows to indicate that folders can be expanded and collapsed with left and right arrow key, but if the list is used in tabs, then these keys are reserved for moving between different tabs. Hence, in these cases, by enabling the tab mode function indicators, the superimposed expand and collapse indicator icons are changed into icons that do not contain misleading arrows. The normal and tab mode indicator icons are superimposed over the default open and closed folder icons in the [Hierarchical_Lists_API_Specification.topic3.1_fig5 Figure 5] below.
Before the created list instance can be displayed, the size and properties of the list have to be set and the control has to be marked ready to draw with themethod. The properties of the list can be changed to non-default values with the method. Size and position of the list can be set freely with some of the methods provided by the class, but the layout for the list is designed for main pane sized area, which should be used in most of the cases.
The client application must also make sure that all the necessary key and pen events are passed to the list, so that the list can respond to the user action properly. As window-owning control, the list will receive the pointer events directly from the control framework, but if the list is constructed as non-window-owning control and the container control contains an overridden version for themethod, then the method must be implemented so that the pen events are mediated to the list. For the key events, the client can either add the container into the control stack and then mediate the required key events from container's method to the list's method, or alternatively, add the list directly to the control stack and let it receive key events directly from the control stack.
[Hierarchical_Lists_API_Specification.topic3.1.1_fig6 Figure 6] shows an example construction sequence on how the list instance can be constructed within a container control provided by the client application.
An example how an instance ofcan be constructed is shown in [Hierarchical_Lists_API_Specification.topic3.1.2_fig7 Figure 7] below. This is essentially similar to the one shown with the instance, only the used class is different, and the container and observer instances are not shown.
The construction of single column style tree list is shown in the figure above. The list can be constructed either as window-owning control, or as non-window-owning component of some window-owning control.
In order to receive list events, the client should also realize theinterface and add it to list observers with the method. The number of observers is not restricted to one, and registered observers, that are no longer needed, can be removed from the list with the method.
The construction of new list items and adding them to the list is implemented by each list specialization, and the construction may be somewhat different in each list type. However, every list has to return an identifier for each item that is added to the list. This identifier can later be used when referring to the added item, for example, when changing the icons of the added item.
When the client first populates the list, the content of the whole list can be added, but it is necessary only for the items on the topmost level of the list hierarchy, and for the items in the expanded branches of the hierarchy. The items in the collapsed nodes can be added whenever the nodes are expanded by the user. Note also that, unless item or one of its descendant is set persistent or marked, it is automatically removed from the list, when its parent node is collapsed. The items may be set persistent when they are added to the list, and after they have been added to the list, their persistence can be changed with themethod.
Theclass contains two methods for adding items to the list:
Tree leaves can be added with themethod, and tree nodes can be added with the method. Both of these methods take four parameters:
node to which the new item is to be added. The parent is specified with the identifier that was received when the parent node was added to the list, or with the constant, if the new item is to be added directly to the tree root.
for the new item.
new item. The possible flags for the item are defined in theenumeration.
is to be redrawn after the item has been added.
The following example shows how an expanded and persistent node is added to the topmost level of the tree, and a persistent leaf to the previously added node.
// Flags used while adding the items. const TInt KPersistent = CAknSingleStyleTreeList::EPersistent; const TInt KExpanded = CAknSingleStyleTreeList::EExpanded;
// Add expanded node to the topmost level of the list. _LIT( KNodeText, "Parent folder" ); TAknTreeItemID parentNode = list->AddNodeL( KAknTreeIIDRoot, KNodeText, KPersistent | KExpanded, EFalse );
// Add leaf to the previously added node (and request redraw). _LIT( KLeafText, "Leaf item" ); TAknTreeItemID leaf = list->AddLeafL( parentNode, KLeafText, KPersistent, ETrue );
Theclass has four different methods for adding items to the list.
The tree nodes in the single column style tree list are named as subtitle rows. New subtitle rows can be added to the list with themethod. The tree leaves in the list are either simple data rows, or core data rows. New simple data rows can be added with the method, and new core data row can be added with the method. The latter has two versions, which can be used depending whether the added core data row has two or three columns.
The parameters of these methods are similar to the ones with theclass. Each of these methods require the identifier of the added items parent node, the text fields for the new item, flags, and the parameter.
Theparameter can be used setting the item properties at the time of its addition. Possible flags for the items in single column style tree list are defined in the enumeration. Note that some of these flags cannot be used with every list item type.
The following example shows how items of different type are added to single column style tree list. Theflag is used for making the created tree structure static, so that the child items are not automatically removed from the list when their parent nodes are being collapsed.
const TInt KPersistent = CAknSingleColumnStyleTreeList::EPersistent;
// Add simple data row to the topmost level of the list. _LIT( KSimpleDataRowText, "Simple data row" ); TAknTreeItemID simpleDataRow = list->AddSimpleDataRowL( KAknTreeIIDRoot, KSimpleDataRowText, KPersistent, EFalse );
// Add subtitle row to the topmost level of the list. _LIT( KSubtitleRowText, "Subtitle row" ); TAknTreeItemID subtitleRow = list->AddSubtitleRowL( KAknTreeIIDRoot, KSubtitleRowText, NULL, EFalse );
// Add core data row with three columns to the subtitle row. _LIT( KColumn1Text, "Core" ); _LIT( KColumn2Text, "Data" ); _LIT( KColumn3Text, "Row" ); TAknTreeITemID coreDataRow = list->AddCoreDataRow( subtitleRow, KColumn1Text, KColumn2Text, KColumn3Text, KPersistent, ETrue );
The text fields of added items can be retrieved with themethods and later changed with the methods.
Core data rows can be set emphasized at the time they are added to the list with theflag, and the setting can be changed later with the method. When core data rows are added with three text field parameters, the third column is enabled to be used in landscape mode, when there is enough space for third column. If construction is done with two text field parameters, the third column usage is by default disabled. This setting can later be changed with the method, if necessary.
A hierarchical list instance stores all the icons used in the list, and these icons can be shared by several list items. When the list is constructed, the list loads a set of default icons. In addition to these default icons, the list client can add new icons to the list, or replace existing icons with the methods provided in theclass.
There are three possible methods for adding new icons to the list:
TInt AddIconL( const TAknsItemID& aId, const TDesC& aFilename, TInt aBitmapId, TInt aMaskId, TScaleMode aScaleMode );
TInt AddIconL( CFbsBitmap* aIcon, CFbsBitmap* aMask, TBool aTransferOwnership, TScaleMode aScaleMode );
TInt AddColorIconL( const TAknsItemID& aId, const TAknsItemID& aColorId, TInt aColorIndex, const TDesC& aFilename, TInt aBitmapId, TInt aMaskId, TRgb aDefaultColor, TScaleMode aScaleMode );
The first method can be used to add a new icon with the necessary parameters needed for loading the icon from the current skin instance or from the given file. The advantage of this method is that it stores the parameters to the list, and reloads the icons automatically on skin change events.
The second method takes pointers to the bitmaps as parameter. When using this method, the client has to handle updating the bitmaps on skin change events itself.
The third method is similar to the first one, but it takes also some icon color related parameters, which are then used for creating a colored icon. As with the first method, the parameters are stored in the list and used in reloading the icon on skin change events.
All of these methods return an identifier, that refers to the added icon. This identifier is to be used by the client when it wishes to set one of the list items to use the icon, to replace the icon with another, or remove the icon from the list. The identifiers for default list icons are defined in the akntreelistconstants.h file.
The following example shows how a new icon can be added to the list with each of these methods.
// Add an icon to to the list using the first method. TInt id1 = list->AddIconL( KAknsIIDQgnIndiS60, AknIconUtils::AvkonIconFileName(), EMbmAvkonQgn_indi_s60, EMbmAvkonQgn_indi_s60_mask, EAspectRatioPreserved );
// Load the same icon from file to bitmaps. CFbsBitmap* bitmap = NULL; CFbsBitmap* mask = NULL; AknIconUtils::CreateIconLC( bitmap, mask, AknIconUtils::AvkonIconFileName(), EMbmAvkonQgn_indi_s60, EMbmAvkonQgn_indi_s60_mask );
// Add the icon to the list with bitmaps using the second method. // The third parameter indicates that ownership of the bitmaps is // transferred to the list. TInt id2 = list->AddIconL( bitmap, mask, ETrue, EAspectRatioPreserved ); CleanupStack::Pop( 2 ); // mask, bitmap
// Finally, add coloured version of the icon using the third method. // The colour EAknsCIQsnTextColorsCG6 used here is the same with list item // text. Colour for highlighted text would be EAknsCIQsnTextColorsCG10. TInt id3 = list->AddColorIconL( KAknsIIDQgnIndiS60, KAknsIIDQsnTextColors, EAknsCIQsnTextColorsCG6, AknIconUtils::AvkonIconFileName(), EMbmAvkonQgn_indi_s60, EMbmAvkonQgn_indi_s60_mask, KRgbBlack, EAspectRatioPreserved );
For each of the three methods represented here, there is also a corresponding method for assigning an identifier for the icon while adding it to the list. These methods can be used also for replacing default icons or previously added icons.
The methods for setting the icons for list items are provided by each list specialization, namely theand classes.
Themethod can be used to set icons for the items in single style tree list. This method requires four parameters:
for which the icon is being changed.
which icon within the specified item is to be changed. Note that the set of applicable icon types depends on the type of the item, for which the icon is being changed.
or identifier of an icon added to the list by the client. The item can be set to use no icon with the constant, and constant can be used to set the item to use the default icon defined for the item type.
after the icon has been changed.
For instance, folder icons for a node item in single style list could be changed as follows:
// Suppose we have bitmaps for expanded and collapsed folder icons. // Add those icons to the list. TInt expandedFolderIconId = list->AddIconL( expandedIconBitmap, expandedIconMask, ETrue, EAspectRatioPreserved ); TInt collapsedFolderIconId = list->AddIconL( collapsedIconBitmap, collapsedIconMask, ETrue, EAspectRatioPreserved );
// Add new node to the topmost level of the list. TAknTreeItemID nodeId = list->AddNodeL( KAknTreeIIDRoot, _L("node"), NULL, EFalse );
// Set the node to use the first added icon as expanded node icon. list->SetIcon( nodeId, CAknSingleStyleTreeList::EExpandedNode, expandedFolderIconId, EFalse );
// Set the node use the second added icon as collapsed node icon. list->SetIcon( nodeId, CAknSingleStyleTreeList::ECollapsedNode, colapsedFolderIconId, ETrue );
The icons added to the list can be used by several list items; the client only has to set several items to use the icons with the same identifier. However, the icon should never be set simultaneously to such types that have different sizes, as this could require the size of icon changed during the draw routine of the list, and result in screen flickering. In general, all the main leaf and node icons have the same size, and all optional indicator icons have the same size.
In theclass the icons are added with the similar method, only difference being the icon types, which are specific to the list type.
As mentioned earlier, theclass contains three methods for replacing icons in the list. The three methods correspond to the three methods that can be used for adding icons to the list. The parameters for each method are otherwise the same as for the corresponding method for adding icons, but these methods take the identifier of the icon as parameter instead of returning it to the caller.
The following example shows how a new icon is added to a single style list, item is set to use the added icon, and then the icon is replaced with another icon.
// Add new icon to to the list. TInt iconId = list->AddIconL( TAknsIIDQgnIndiS60, AknIconUtils::AvkonIconFileName(), EMbmAvkonQgn_indi_s60, EMbmAvkonQgn_indi_s60_mask, EAspectRatioPreserved );
// Add leaf item to the list. TAknTreeItemID leafId = list->AddLeafL( KAKnTreeIIDRoot, _L("leaf"), NULL, EFalse );
// Set leaf to use added icon as its main icon. list->SetIcon( leafId, CAknSingleStyleTreeList::ELeaf, iconId, EFalse );
// Replace the previously added icon with coloured version of it. list->AssignColorIconL( iconId, TAknsIIDQgnIndiS60, KAknsIIDQsnTextColors, EAknsCIQsnTextColorsCG6, AknIconUtils::AvkonIconFileName(), EMbmAvkonQgn_indi_s60, EMbmAvkonQgn_indi_s60_mask, KRgbBlack, EAspectRatioPreserved );
// Redraw list. list->DrawNow();
After the icon has been replaced with one of the assign methods, every icon using the identifier of the replaced icon immediately refers to the new icon. This could, for instance, be used for changing the default file icon to some other icon as follows:
// Replace default file icon. list->AssignIconL( AknTreeListIconID::KDefaultFileIndication, TAknsIIDQgnIndiS60, AknIconUtils::AvkonIconFileName(), EMbmAvkonQgn_indi_s60, EMbmAvkonQgn_indi_s60_mask, EAspectRatioPreserved );
Icons that are no longer needed in the list can be removed with themethod. When the item refers to an icon that has been removed from the list, no icon is drawn for that specific place, unless the new icon using the same icon identifier has already been added to the list. Default icons cannot be removed from the list, only replaced.
The client application can remove items from the list with themethod. The item identifier specifying the removed item is given as a parameter to the method. If the removed item is a node, then the content of the node is removed from the list as well. Setting list items persistent does not affect the removal in any way.
When items are removed from the list, the list notifies its observers of each removal. After the notifications, the identifiers assigned to removed items can no longer be used.
Note that any icons that were added to the exclusive use of the removed tree items, and are no longer needed, should also be removed from the list with themethod.
Tree list nodes can be expanded by the client application with themethod. This is illustrated in [Hierarchical_Lists_API_Specification.topic3.4_fig8 Figure 8]. Item identifier of the expanded node has to be passed as parameter to the method. The method panics, if the specified item does not exist in the list, or if it is not a node. The method can be used to check whether the list contains the specified item, and the and methods can be used to check whether the specified item is a leaf or a node.
Before the specified node is expanded, the list notifies all of its observers of the expansion event. This enables the client application to add content to the list only when it is needed by the list. After the client has had the possibility to update the content of the expanded node, the node state is changed to the expanded. After this, the list is redrawn, if it was requested with theparameter.
The expand event may be triggered also by key or pen event as a result of user action. The observers are notified of the event also in this case.
The nodes in the list can be collapse also by the user with pen or and key events. The observers of the list are notified of the event. In addition to these events, the client application can provide collapse command in softkey or options menu. In these cases, the list nodes can be collapsed by the client application with themethod. This is shown in [Hierarchical_Lists_API_Specification.topic3.5_fig9 Figure 9].
When node is collapsed, the list first notifies the observers of the collapse event. Then, it removes every child item of the collapsed node, that is not set marked or persistent, and does not contain any descendants that are set either marked or persistent. The descendants of the removed items are removed as well, and the observers are notified of every removal.
The client application can set the focused item in the list with themethod. The method requires the identifier of the new focused item, and index specifying the desired location for the item in the visible part of the list.
Focus can also be moved by the user with key and pen events. Observers of the list are notified of focus changes with theevent.
The leaf items in the list can be selected by the user when they are focused. Observers of the list get notification of the event via themethod with the event as the parameter and the item identifier of the selected item as the parameter. Client applications should respond to these event by performing some item related operation, for example, opening the selected file, displaying selected message, and so on.
By default, the list items reside within their parent nodes in the order in which they were first added to the node. The client application can change the ordering of the items with the help of theinterface. By providing an implementation of the interface and setting the interface to be used in the list, the interface is thereafter used in determining the ordering of the list items within their parent nodes.
Theinterface contains the pure virtual method, for which the client application must provide an implementation. The method gets two item identifiers as parameters, and the implementation has to choose an integer return value specifying the order between the given items.
Themethod sets the interface implementation to be used by the list. This method also sorts the list by sorting each node in the list according to the given interface. Only one ordering interface can be in use at a time, and ordering can be removed altogether from use by giving NULL pointer as pointer to new ordering interface.
After the custom ordering interface is set for the list, it is used whenever items are moved within the list with themethod. The interface cannot be used in determining the items position during the addition, because the client receives the item identifier for the added item only after it has been added. Therefore, even with the custom ordering interface in use, new items are inserted to the end of their parents node. After new items have been added to some node, the client can sort the contents of that node with the method. The sorting can be set to include the whole branch specified by the node, or only its immediate children.
For example, if custom ordering is in use and new item is added to the list, the item is inserted to the end of the node. To change the item to correct position amongst its siblings, the content of the parent node could be sorted as follows:
// Add new item to a node in a list without redrawing the list. list->AddLeafL( parentId, _L("Text"), NULL, EFalse );
// Sort the content of parent node and request redraw. list->Sort( parentId, EFalse, ETrue );
The leave mechanism of Symbian OS environment is used to handle memory exhaustion. The panic mechanism is used in cases where the list client tries to use list interface incorrectly by referring to non-existent list items, or items of invalid type. The used panic codes are defined in aknhlistpanic.h file.
Memory consumption of the list depends solely on the content added to the constructed list instance. Memory overhead for list items, which does not include the text strings or icons, is somewhere in the range from 50 bytes to 100 bytes per item, depending on the item type.
Hierarchical Lists API does not explicitly support any kinds of extensions to it.