diff -r 923ff622b8b9 -r 4633027730f5 src/hbcore/gui/hbmenu.cpp --- a/src/hbcore/gui/hbmenu.cpp Tue Jul 06 14:36:53 2010 +0300 +++ b/src/hbcore/gui/hbmenu.cpp Wed Aug 18 10:05:37 2010 +0300 @@ -136,10 +136,12 @@ void HbMenuPrivate::delayedLayout() { - createMenuView(); - if(menuItemView) - menuItemView->doDelayedLayout(); - delayMenuConstruction = false; + if (delayMenuConstruction) { + createMenuView(); + if(menuItemView) + menuItemView->doDelayedLayout(); + delayMenuConstruction = false; + } } void HbMenuPrivate::changeToOptionsMenu() @@ -210,9 +212,9 @@ } /* - Returns current focusable action based on current row of the menuItemView or index if specified. - If there is no focusable action it returns 0. - Also returns the active item representing the active action or 0. + Returns current focusable action based on current row of the menuItemView or index if specified. + If there is no focusable action it returns 0. + Also returns the active item representing the active action or 0. */ HbAction *HbMenuPrivate::activeAction(HbMenuItem *&activeItem) const { @@ -229,7 +231,7 @@ } /* - Convenience overload + Convenience overload */ HbAction *HbMenuPrivate::activeAction() const { @@ -238,8 +240,8 @@ } /* - Opens a submenu for activeItem. If activeItem is 0 it uses activeAction() to determine active item - and opens submenu for it if active action has submenu. + Opens a submenu for activeItem. If activeItem is 0 it uses activeAction() to determine active item + and opens submenu for it if active action has submenu. */ void HbMenuPrivate::openSubmenu(HbMenuItem *activeItem) { @@ -298,8 +300,8 @@ } } -/*! - Handles menu close +/* + Handles menu close */ void HbMenuPrivate::closeMenu() { @@ -377,53 +379,133 @@ @beta @hbcore \class HbMenu - \brief HbMenu is a menu widget for use in HbView. - - \image html hbmenu.png A menu with checkable items and a sub-menu. + \brief The HbMenu class provides a widget that shows a list of options. - Use an HbMenu to show a list of options. There are two main types of menus: + A menu consists of a list of options that the user can select. When the user selects + an option, it triggers a command. Menus are hidden by default and open in response + to an action from the user. For this reason, the toolbar (HbToolBar class) usually + provides access to the most important commands (called first order commands) and + menus provide access to second order commands. - - The view options menu - - Context menus (popup menus) + \image html hbmenu.png An options menu with a submenu that has checkable actions + + You can use the %HbMenu class to create the following: - There is one view options menu for each view. - It is shown by tapping the title bar. You can access the view options menu by calling - HbView::menu() which returns a pointer to a new empty menu if one does not already exist. + - An \b options \b menu, which shows options that relate to the whole view. It is + a drop-down menu that is directly owned by the view (HbView object). It opens when the + user taps on the view's title bar. You can access a view's options menu by calling + HbView::menu(). This returns a pointer to a new empty menu if the menu does not + already exist. A view can have only one options menu. - You can create any number of context menus. - Context menus are usually invoked by a user action, such as tapping a widget. + - A \b context \b menu, which is a pop-up menu that shows options that relate to a + specific item, rather than to the entire view. It typically opens in response to a + UI event, such as a tap on a widget or a particular point within the view. You can + create any number of context menus. + + A menu is a list of actions, which are objects of class HbAction. A menu can contain: - A menu contains a list of items. You can add three kinds of items to a menu: + - \b Separators, which are actions that group related items. Use addSeparator() or + insertSeparator() to create a separator and add it to a menu. + + - Actions that trigger a \b submenu to open. Submenus are menus that are nested within + another menu. Use addMenu() or insertMenu() to add a submenu to a menu. Although it is + possible to nest submenus within other submenus, generally this is not considered good + design practice. - - Actions - - Sub-menus - - Separators + - \b Action \b items, which represent the menu options. Use addAction() and insertAction() to + add an action to a menu. Use addActions() and insertActions() to add and insert multiple + actions in one operation. Use clearActions() to clear all of the actions from a menu and + removeAction() to remove individual actions from a menu. - An action is an object of class HbAction that performs an action when it is triggered. - Use addAction() to add an action to a menu. Actions can be checkable (QAction::setCheckable). - Use clearActions() to clear all actions from a menu. - Use removeAction() to remove individual actions from a menu. - - A sub-menu is a menu that is nested within another menu. Use addMenu() or insertMenu() to add a sub-menu to a menu. - Sub-menus can be nested within sub-menus. + The order of the actions within the menu controls the order of the options that the user sees. + When you add the actions directly to the menu, addAction() and addActions() append the actions + to the end of the menu and insertAction() and insertActions() enable you to specify the position. + For options menus, however, there is an alternative approach to ordering the action items. + This is to call HbView::addAction() to add actions to the \b view and let the view distribute + them to the options menu or toolbar, depending on the preference set, the UI command distribution + template, and taking into account the available space in the toolbar. The menu and toolbar + then order the actions according to their defined roles and the UI command container template. + This approach makes it easier to create consistent user interfaces and applications that + work well on a variety of different devices. - Separators group related items in a menu. - Use addSeparator() or insertSeparator() to create and add a separator to a menu. - - \image html hbmenu.png A menu with checkable actions and a sub-menu. + An action item can be checkable, which means that it has an on/off state. You specify that an + action item is checkable by calling \c setCheckable() on the action. Use \c isChecked() + to discover if an action is checked. You can also use the QAction::toggled(bool) signal to + receive notification of a change in the checked status. - After you add an action to your menu, you specify a receiver object and its slot (you can also - add an action and specify a receiver slot at the same time). - The receiver is notifed when the action is triggered (QAction::triggered()). - HbMenu also has a triggered() menu signal, which signals which HbAction was triggered in the menu. + After you add an action item to a menu, you can connect its \link HbAction::triggered() + triggered()\endlink signal to a slot on a receiver object. Alternatively you can use the + addAction(const QString &, const QObject *, const char *) overload to add an action item and + specify a receiver slot at the same time. The receiver is notified when the action item + is \link HbAction::triggered() triggered()\endlink. - An example of how to create an option menu. + You can also connect the HbMenu::triggered(HbAction*) signal to a receiver object's slot. This + signal is emitted when any menu action is triggered. You can find out which action was + triggered from the HbAction parameter. + + \section _usecases_hbmenu Using the HbMenu class + + \subsection _uc_001_hbmenu Creating an options menu + + The following example creates an options menu for a view. \snippet{ultimatecodesnippet/ultimatecodesnippet.cpp,2} - An example of how to create and show a context menu from the gesture. + \subsection _uc_002_hbmenu Creating a context menu + + The following example creates a context menu and shows it in response to a tap and hold gesture. \snippet{ultimatecodesnippet/ultimatecodesnippet.cpp,54} - \sa HbDialog, HbView + \subsection _uc_004_hbmenu Adding actions to the view + + The following example creates two action items, specifies their command roles, and then + adds them to the view. The view places them in the menu or toolbar according to the + priorities of the actions and the space available in the toolbar and the menu orders them + according to their roles and priorities. + + \code + HbAction* actionExit = new HbAction(tr("Exit")); + actionExit->setCommandRole(HbAction::ExitRole); + + HbAction* actionHelp = new HbAction(tr("Help")); + actionHelp->setCommandRole(HbAction::HelpRole); + + // Add actions to the view. + myView->addAction(actionExit); + myView->addAction(actionHelp); + \endcode + + \subsection _uc_003_hbmenu Creating action items that are checkable + + You can create a menu that contains multiple checkable actions (actions with checkbox behavior). + For simple checkbox behavior, just set the actions to be checkable by calling \c setCheckable(true). + For example: + + \code + ... + checkAction1->setCheckable(true); + checkAction2->setCheckable(true); + checkAction3->setCheckable(true); + ... + \endcode + + \subsection _uc_005_hbmenu Creating radio button style options + + To create a group of related actions, only one of which can be checked (radio button behavior), + create a QActionGroup object and add the actions to that. For example: + + \code + HbAction *redAction = menu->addAction(tr("Red")); + HbAction *blueAction = menu->addAction(tr("Blue")); + + redAction->setCheckable(true); + blueAction->setCheckable(true); + + QActionGroup *actionGroup = new QActionGroup(view); + actionGroup->addAction(redAction); + actionGroup->addAction(blueAction); + \endcode + + \sa HbView, HbToolBar, HbAction */ /*! @@ -434,35 +516,30 @@ /*! \fn void HbMenu::triggered(HbAction *action) - This signal is emitted when one of the action items is selected. - \param action the action that was triggered in the menu. - */ + This signal is emitted when one of the menu options is selected. + \param action The action that was selected. +*/ /*! \enum HbMenu::MenuType - This enum describes different types of HbMenu. + The MenuType enum identifies the possible HbMenu types. */ /*! \var HbMenu::ContextMenu - - ContextMenu is a menu which position is set by user. + A popup menu. */ /*! - \var HbMenu::OptionMenu - - OptionMenu is set by HbView. Its position cannot be changed. + \var HbMenu::OptionsMenu + The main options menu in a view. Its position cannot be changed. */ /*! \var HbMenu::SubMenu - - Menu becomes SubMenu when it is added to another menu. + A submenu, which is a menu that has been added to another menu. */ /*! Constructs a menu with \a parent graphics item. - - \param parent is the parent graphics item. */ HbMenu::HbMenu(QGraphicsItem *parent) : HbPopup(*new HbMenuPrivate, parent) @@ -475,8 +552,6 @@ /*! Constructs a menu with \a title and \a parent graphics item. - \param title is the menu title. - \param parent is the parent graphics item. */ HbMenu::HbMenu(const QString &title, QGraphicsItem *parent) : HbPopup(*new HbMenuPrivate, parent) @@ -498,6 +573,9 @@ d->init(); } +/*! + Destructor +*/ HbMenu::~HbMenu() { if (!scene() || !scene()->property("destructed").isValid()) { @@ -527,9 +605,12 @@ } /*! - Creates a new action with title \a text. It adds the newly created action to the menu's list of actions. - \param text is the text for the new action. - \return the new action. + Creates a new action and adds it to the end of the menu. + + \overload + + \param text The menu text for the new action. + \return The new action. */ HbAction *HbMenu::addAction(const QString &text) { @@ -539,12 +620,16 @@ } /*! - Creates a new action with \a text. - The action's triggered() signal is connected to the - \a receiver's \a member slot. The function adds the newly created - action to the menu's list of actions. - \return the new action. - */ + Creates a new action, adds it to the end of the menu and connects the action's + \link HbAction::triggered() triggered()\endlink signal to a receiver's slot. + + \overload + + \param text The menu text for the new action. + \param receiver The object that is to receive the new action's signal. + \param member The slot on the receiver to which the action's signal is to connect. + \return The new action. +*/ HbAction *HbMenu::addAction(const QString &text, const QObject *receiver, const char *member) { HbAction *action = new HbAction(text, this); @@ -554,33 +639,35 @@ } /*! - Adds \a menu as a sub-menu. - \param menu is the menu that is added to this one. - \return the action for the added sub-menu. - */ + Adds \a menu to the current menu as a submenu. + + \return The action for the added submenu. +*/ HbAction *HbMenu::addMenu(HbMenu *menu) { return insertMenu(0, menu); } /*! - Creates a new HbMenu with \a title and adds it to this menu. - \param title is the menu title. - \return the new menu. + Creates a new HbMenu with \a title and adds it to the current menu as a submenu. + + \return The new menu. */ HbMenu *HbMenu::addMenu(const QString &title) { HbMenu *menu = new HbMenu(title); - addMenu(menu); + if ( menu ) { + menu->setParent(this); + addMenu(menu); + } return menu; } /*! - Inserts \a menu before action \a before. - \param before is the action before which this new menu is inserted. - \param menu is the menu that is inserted. + Inserts \a menu into the current menu as a submenu before the \a before action. + \return the action associated with the inserted menu. - */ +*/ HbAction *HbMenu::insertMenu(HbAction *before, HbMenu *menu) { QObject::connect(menu, SIGNAL(triggered(HbAction*)), this, SLOT(_q_subMenuItemTriggered(HbAction*))); @@ -592,8 +679,11 @@ } /*! - \return the action associated with this menu. - */ + Returns the action that is directly associated with a menu (rather than actions that are contained + within the menu). Although all menus have an assoicated action, it is only actually used for submenus. + The parent menu uses a submenu's action to trigger the opening of the submenu. A submenu's action + also defines the submenu's title. +*/ HbAction *HbMenu::menuAction() const { Q_D(const HbMenu); @@ -601,26 +691,27 @@ } /*! - Creates a new separator action, which is an action that returns \c true from HbAction::isSeparator(), - and adds it to this menu's list of actions. - \return the new separator action + Creates a new separator and adds it to the current menu's list of actions. A separator + is an action for which HbAction::isSeparator() returns \c true. - \sa insertSeparator - */ + \return The new separator action. + + \sa insertSeparator() +*/ HbAction *HbMenu::addSeparator() { - //functionality removed for now + //functionality removed for now //return insertSeparator(0); return 0; } /*! - Inserts a new separator action and inserts it into this menu's list of actions before \a action. - \param before is the action before which the separator is inserted. - \return the new action. + Creates a new separator and inserts it into the current menu's list of actions before \a before. + A separator is an action for which HbAction::isSeparator() returns \c true. - \sa addSeparator - */ + \return The new separator action. + \sa addSeparator() +*/ HbAction *HbMenu::insertSeparator(HbAction *before) { Q_UNUSED(before); @@ -635,8 +726,9 @@ } /*! - \return the current active action, or 0 if no action item is currently active. - */ + Returns the active action or 0 if no action item is currently active. The active action is + the last action that was triggered, unless this has been overridden by a call to setActiveAction(). +*/ HbAction *HbMenu::activeAction() const { Q_D(const HbMenu); @@ -644,8 +736,8 @@ } /*! - Sets the active action in menu. If \a action is not found from the list of - menu actions then the current active action remains active. + Sets \a action as the current active action in the menu. If \a action is not + found in the list of menu actions, the action that is currently active remains active. \sa activeAction() */ @@ -658,17 +750,17 @@ } /*! - \return \c true if the menu is empty (contains no actions) and \c false otherwise. + Returns \c true if the menu contains no actions and \c false otherwise. - \sa clear() - */ + \sa clearActions() +*/ bool HbMenu::isEmpty() const { return actions().isEmpty(); } /*! - Sets the menu title. For a sub-menu, the title is the sub-menu action text. + Sets the menu title. For a submenu, the title is the submenu's action text. \sa title() */ @@ -678,9 +770,7 @@ } /*! - Returns the menu title. For a sub-menu, the title is the sub-menu action text. - - \return the menu title. + Returns the menu title. For a submenu, the title is the submenu's action text. \sa setTitle() */ @@ -690,9 +780,8 @@ } /*! - Returns the menu type. By default a menu is a context menu. + Returns the menu type. The default menu type is context menu. - \return the menu type. */ HbMenu::MenuType HbMenu::menuType() const { @@ -700,9 +789,6 @@ return d->menuType; } -/*! - \reimp - */ QVariant HbMenu::itemChange( GraphicsItemChange change, const QVariant & value ) { Q_D(HbMenu); @@ -711,7 +797,7 @@ d->closeMenu(); } if (change == QGraphicsItem::ItemVisibleChange) { - if (value.toBool() && d->delayMenuConstruction) { + if (value.toBool() && d->polished) { d->delayedLayout(); } if (value.toBool()) { @@ -724,9 +810,6 @@ return HbPopup::itemChange(change,value); } -/*! - \reimp -*/ bool HbMenu::event(QEvent *event) { Q_D(HbMenu); @@ -754,49 +837,50 @@ return HbPopup::event(event); } -/*! - \reimp - */ void HbMenu::polish(HbStyleParameters ¶ms) { - Q_D(HbMenu); - const QString NumberOfCols = "number-of-columns"; - params.addParameter(NumberOfCols); + if (isVisible()) { + Q_D(HbMenu); + const QLatin1String NumberOfCols("number-of-columns"); + params.addParameter(NumberOfCols); - if (d->mSubMenuItem) { - const QString RightMargin = "submenu-right-offset"; - const QString DownMargin = "submenu-bottom-margin"; - params.addParameter(RightMargin); - params.addParameter(DownMargin); + if (d->mSubMenuItem) { + const QLatin1String RightMargin("submenu-right-offset"); + const QLatin1String DownMargin("submenu-bottom-margin"); + params.addParameter(RightMargin); + params.addParameter(DownMargin); + + HbPopup::polish(params); - HbPopup::polish(params); - - if (!params.value(RightMargin).isNull()) { - d->mRightMargin = params.value(RightMargin).toDouble(); + if (!params.value(RightMargin).isNull()) { + d->mRightMargin = params.value(RightMargin).toDouble(); + } + if (!params.value(DownMargin).isNull()) { + d->mDownMargin = params.value(DownMargin).toDouble(); + } + d->setSubMenuPosition(); + } else { + HbPopup::polish(params); } - if (!params.value(DownMargin).isNull()) { - d->mDownMargin = params.value(DownMargin).toDouble(); + + if (!params.value(NumberOfCols).isNull()) { + int cols = params.value(NumberOfCols).toInt(); + if (d->mNumberOfColumns != cols) { + d->mNumberOfColumns = cols; + if (d->menuItemView) { + d->menuItemView->updateContainer(); + } + } } - d->setSubMenuPosition(); + d->delayedLayout(); } else { HbPopup::polish(params); } - - if (!params.value(NumberOfCols).isNull()) { - int cols = params.value(NumberOfCols).toInt(); - if (d->mNumberOfColumns != cols) { - d->mNumberOfColumns = cols; - if (d->menuItemView) { - d->menuItemView->updateContainer(); - } - } - } } /*! - \reimp - Returns the shape of this item as a QPainterPath. - */ + Returns the shape of this item as a QPainterPath. +*/ QPainterPath HbMenu::shape() const { /*QRectF rect = QRectF(-1.0, -1.0, boundingRect().width() + 1.0, boundingRect().height() + 1.0); @@ -810,18 +894,12 @@ } /*! - - Opens the menu and returns immediately. - - Connects triggered(HbAction*) signal to the slot specified by \a - receiver and \a member. The signal will be disconnected when menu - is closed. - - An example of how to create a simple context menu and show it - \snippet{ultimatecodesnippet/ultimatecodesnippet.cpp,54} - - - */ + Displays the menu on the screen and returns immediately. It can also connect the HbMenu::triggered() + signal to a specified slot. The signal is disconnected when the menu closes. + + \param receiver The object that is to receive the signal. + \param member The slot on the receiver to which the signal is to connect. +*/ void HbMenu::open( QObject *receiver, const char *member ) { Q_D(HbMenu);