[Bada] Creating and Using Option and Context Menus in Bada

An option menu is created using the OptionMenu class and context menu uses the ContextMenu class. For the example in this tutorial, I’m using an application that with text on the screen and a left soft key. Clicking on the text brings up a context menu. The options menu is dispalyed when the left soft key or the option menu handle are pressed. When an item is selected in either menu, a dialog pops up to display the corresponding item’s action id.

The following is a snippet of the header file for DemoForm, which is the Form containing the contents displayed in the application:

...
class DemoForm :
	public Osp::Ui::Controls::Form
	,public Osp::Ui::IActionEventListener
	,public Osp::Ui::ITouchEventListener
{
...
private:
	Osp::Ui::Controls::OptionMenu *_pOptionsMenu;
	Osp::Ui::Controls::ContextMenu *_pContextMenu;
    Osp::Ui::Controls::Popup *_pPopup;
    ...
public:

    void OnActionPerformed(
        const Osp::Ui::Control &source, 
        int actionId);
    ...
    void OnTouchPressed(
        const Osp::Ui::Control &source, 
        const Osp::Graphics::Point &currentPosition, 
        const Osp::Ui::TouchEventInfo &touchInfo);
};
...

The form is implementing the IActionEventListener and ITouchEventListener interfaces (lines 4 and 5) so that it can handle the user’s interactions. Objects that are handling the user’s interactions need to implement either of these interfaces, depending on which type of interaction they are interested in.

The two public methods, OnActionPerformed and OnTouchPressed, are from the IActionEventListener and ITouchEventListener interfaces, respectively. Note that ITouchEventListener actually specifies more methods, such as OnTouchReleased and OnTouchMoved, but I have omitted them for the sake of brevity. Besides, OnTouchPressed is the only method, from ITouchEventListener that we are interested in. When OnActionPerformed or OnTouchPressed are called, they need to be able to access the OptionMenu, ContextMenu or the Popup (for displaying the selected item’s action id) to bring them up.

In the implementation of the DemoForm class, the option and context menus are set up in the following method:

result
DemoForm::OnInitializing(void)
{
    result r = E_SUCCESS;

    // This is to register the action ID for bringing
	// up the options menu.
	SetOptionkeyActionId(SHOW_OPTIONS_ACTION);
	AddOptionkeyActionListener(*this);
	SetSoftkeyActionId(SOFTKEY_0, SHOW_OPTIONS_ACTION);
	AddSoftkeyActionListener(SOFTKEY_0, *this);

    _pOptionsMenu = new OptionMenu();
    _pOptionsMenu->Construct();
    _pOptionsMenu->AddItem(L"Accounting", 101);
    _pOptionsMenu->AddItem(L"Science", 102);
    _pOptionsMenu->AddItem(L"Engineering", 103);
    _pOptionsMenu->AddItem(L"Art", 104);

    _pOptionsMenu->AddSubItem(1, L"Physics", 105);
    _pOptionsMenu->AddSubItem(1, L"Chemistry", 106);
    _pOptionsMenu->AddSubItem(1, L"Biology", 107);

    _pOptionsMenu->AddSubItem(2, L"Software", 108);
    _pOptionsMenu->AddSubItem(2, L"Civil", 109);
    _pOptionsMenu->AddSubItem(2, L"Mechanical", 110);
    _pOptionsMenu->AddActionEventListener(*this);

    _pContextMenu = new ContextMenu();
    _pContextMenu->Construct(Point(0, 0), CONTEXT_MENU_STYLE_LIST);
    _pContextMenu->AddItem("Apple", CONTEXT_APPLE_ITEM);
    _pContextMenu->AddItem("Banana", CONTEXT_BANANA_ITEM);
    _pContextMenu->AddItem("Pear", CONTEXT_PEAR_ITEM);
    _pContextMenu->AddActionEventListener(*this);


    Label *contextLabel = static_cast<Label*>(GetControl(L"TextLabel"));
    contextLabel->AddTouchEventListener(*this);

	return r;
}

The option key is configured to use an action id of SHOW_OPTIONS_ACTION at line 8 and the form is added to receive notification when the key is pressed at line 9. Similarly, lines 10 and 11 configure which action id (also SHOW_OPTIONS_ACTION) is used when the left soft key is pressed and which object will receive the action. Since the object being added to receive the action is this, the form’s OnActionPerformed method will be invoked when the keys are pressed.

The option menu is created and set up between lines 13 and 27. The call to Construct initialises the menu. In fact, most other controls also has this method. The method should be always be called to initialise the control. The last numeric arguments in the calls to AddItem and AddSubItem are the action ids that will be provided when the items are selected. These are the action ids associated with the menu items and should provide a way of distinguishing which menu item is selected. The objects registered to receive notifications when items from the menu are selected (in this case, the form), will have their OnActionPerformed methods invoked with these numbers.

The context menu is created and setup in a similar fashion (lines 29 to 34). Since the form is defined in an external resource file (see the source files), the label needs to be obtained from the form (line 36) in order to be able to add the touch event listener (line 37). Now, when the text label is touched, one or more of the methods required by the ITouchEventListener methods will be called (depending on which type of interaction).

The listing for the OnActionPerformed method:

void
DemoForm::OnActionPerformed(const Control& source, int actionId)
{
	switch (actionId) {
	    case SHOW_OPTIONS_ACTION:
	        _pOptionsMenu->SetShowState(true);
	        _pOptionsMenu->Show();
	        break;
	    case HIDE_POPUP:
	        hidePopup();
	        break;
	    default:
	        hidePopup();

	        // Display a popup showing the selected action.
	        _pPopup = new Popup();
	        _pPopup->Construct(L"SelectionPopup");
            Label *label = static_cast<Label*>(
                    _pPopup->GetControl(L"MessageLabel", true));
	        String text = String("Action id is ");
	        text.Append(actionId);
	        label->SetText(text);

            Button *closeButton = static_cast<Button *>(
                    _pPopup->GetControl(L"CloseButton", true));
	        closeButton->SetActionId(HIDE_POPUP);
	        closeButton->AddActionEventListener(*this);

	        _pPopup->SetShowState(true);
	        _pPopup->Show();
	}
}

As mentioned before, the method OnActionPerformed will be invoked when the option or soft keys are pressed or when an item is selected from either of the context or option menus. The parameter actionId corresponds to the action ids that were set for the keys back in OnInitializing. In this example, pressing the option or soft keys will result in it being set to SHOW_OPTIONS_ACTION. When it is received, the popup menu is displayed (lines 5 to 8). Notice that showing menu required two method calls – firstly to SetShowState and then to Show. According to the documentation for SetShowState, simply calling the method with a value of true is not enough:

Even if this method (SetShowState) is invoked, the control is not drawn or shown.
To draw and show the control, use Draw() and Show() methods.
Once the control’s show state is set to false, you need to set show state to true again before you draw and show the control.

However, to hide the menu, you only need to call SetShowState with a value of false. These rules to hide and show also apply to other Bada components. Even the same calls are required for displaying the popup at lines 29 and 30. The method hidePopup will hide popup with by calling SetShowState with a value of false (see the listing for hidePopup later).

The default case (lines 13 to 30) creates and sets up the Popup that will display the selected item’s action id. In order to be able to dismiss the popup, the popup’s close button is configured to use the HIDE_POPUP action id and the action is received by the form (at lines 9 to 11). The listing for the method for hidePopup method:

void
DemoForm::hidePopup()
{
    if (_pPopup != NULL) {
        _pPopup->SetShowState(false);
        delete _pPopup;
        _pPopup = NULL;
    }
}

As mentioned before, once a control is displayed, it it hidden by simply calling SetShowState with a value of false. Since a new popup is being created each time it needs to be displayed (see the listing for OnActionPerformed), the popup needs to be deleted. However, it is important to know that not all controls should be deleted in a similar way. The reason for this is contained in this extract from the SDK’s faq on the UI:

You must create forms and all controls on the heap. However, once the controls have been added to the Form (or container), and the Form attached to the Frame, the application framework takes care of all the deleting when the application terminates. If you want to explicitly remove a control, use the RemoveControl() method instead of delete. Otherwise the framework tries to delete the control a second time when the parent Container is being destroyed.

Finally, in order to display the context menu when the text label is touched, the OnTouchPressed is defined:

void
DemoForm::OnTouchPressed(const Osp::Ui::Control &source, 
    const Osp::Graphics::Point &currentPosition, 
    const Osp::Ui::TouchEventInfo &touchInfo)
{
    Rectangle sourceBounds = source.GetBounds();
    Point touchPoint = touchInfo.GetStartPosition();
    int x = sourceBounds.x + touchPoint.x;
    int y = sourceBounds.y + touchPoint.y;

    _pContextMenu->SetPosition(Point(x, y));
    _pContextMenu->SetShowState(true);
    _pContextMenu->Show();
}

Unlike the option menu, the context menu needs have its position set to appear in the correct place. In most cases, the position of the context menu will usually depend on the location of the control that the context menu is for.

The source code for this tutorial can be downloaded from here.

Advertisements

One Response to [Bada] Creating and Using Option and Context Menus in Bada

  1. M.A says:

    This post was too usefull, thank you very much…

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: