Using menu sections in menu bar resource statements

Figure 1. Menu sections in an Options menu

The use of menu sections provides a means of combining menu bar resource declarations in Options menus. One example of how this could be used would be an application with two views. Three MENU_BAR resources could be defined as follows:

  • an application menu section, which would be common to both views

  • a menu section for view 1, which would contain options items unique to this view

  • a menu section for view 2, which would contain options items unique to this view

Combining menu sections

The menu sections that are combined for an Options menu are defined in the MENU_BAR resource. This resource lists all the sections that will be combined to form the menu. The menu sections are combined from bottom to top (for example, system sections such as 'Edit' go at the bottom of the menu while context sections such as 'Open' go at the top of the menu). A menu bar is defined as follows:


RESOURCE MENU_BAR r_menuapp_menu_bar
    {
    titles =
        {
        MENU_TITLE { menu_pane = r_system_menu; },
        MENU_TITLE { menu_pane = r_app_menu; },
        MENU_TITLE { menu_pane = r_view1_options_menu; },
        MENU_TITLE { menu_pane = r_context1_menu; }
        };
    }

The default MENU_BAR resource is declared in EIK_APP_INFO or AVKON_VIEW

Changing menu sections

You can use the following method to change the MENU_BAR resource that is used by the application to change the menu sections at any time within the application:

iEikonEnv->AppUiFactory()->MenuBar()->
   SetMenuTitleResourceId(MENU_BAR_RESOURCE_ID);

This sets the whole menu bar and should be performed every time one of the sections needs to change its contents. Therefore, you should define as many MENU_BAR resources as there are possible combinations of menu sections. That is, a menu bar should be defined for each combination of view and context options. Note also that if view architecture is used, and the view’s own menu system is in use, it is this menu bar’s contents that need switching, as follows:

iMyView->MenuBar()->
     SetMenuTitleResourceId(MENU_BAR_RESOURCE_ID);

Changing menu items in menu sections

Individual menu items in a menu section may be changed whenever the menu is displayed. This allows the application to show and hide (or remove and add) menu items in response to the application state. In the traditional Symbian OS UI architecture, you should override MEikAutoMenuObserver::DynInitMenuPaneL() in the UI controller. In the View architecture, you should override MEikAutoMenuObserver::DynInitMenuPaneL() in the view controller. An example of such an override is as follows:

void CMyAppUi::DynInitMenuPaneL(TInt aResourceId, 
    CEikMenuPane* aMenuPane)
    {
    if(aResourceId != R_SYSTEM_MENU_PANE)
        return; // in this example only interest in system
                // pane

    // First hide all
    aMenuPane->SetItemDimmed(ECmdCut, ETrue);
    aMenuPane->SetItemDimmed(ECmdCopy, ETrue);
    aMenuPane->SetItemDimmed(ECmdPaste, ETrue);

    // Show according to application state
    if(...)
        {
        aMenuPane->SetItemDimmed(ECmdCut, EFalse);
        aMenuPane->SetItemDimmed(ECmdCopy, EFalse);    
        }
    else
        {
        aMenuPane->SetItemDimmed(ECmdPaste, EFalse);
        }
    } 

This method is called by the framework after each of the sections has been added to the menu, and is called with the resource ID of the section that has just been added and the menu pane object that is being built.

You can also override MEikAutoMenuObserver::DynInitMenuBarL(TInt aResourceId, CEikMenuBar* aMenuBar) in the UI controller or view controller, depending on your UI architecture. This gets called before any sections are added to the menu, and can be used to dynamically change the sections that will be added to the menu. This could be used to change the resource ID of the context menu section for a certain application state.