Introduction

Most applications use a menu system for basic tasks such as "new", "open", "exit". This tutorial shows the basics of setting up a menu system in your application using QuickGUI.

Assumptions

It is assumed that you have already worked through the previous tutorials, and have the basic initialization and input code working.

Getting started

Creating the Toolbar

The first thing we need to do is create a Toolbar. The toolbar is what all menus are anchored to. We'll need to initialize the toolbar with the following code:

QuickGUI::ToolBarDesc* tbd = QuickGUI::DescManager::getSingleton().getDefaultToolBarDesc();

This sets up a Toolbar instance, tbd, with all of the default Desc information (see QuickGUI Widget Desc class for more information about the Desc classes). Next, we'll call resetToDefault(), which ensures all the default widget information is copied to the Toolbar instance (and clearing out any current information):

tbd->resetToDefault();

Next, we'll provide a name for the widget, and define its overall size and position:

tbd->widget_name = "TestToolBar";
  tbd->widget_dimensions = QuickGUI::Rect(0,0,800,20);

Lastly, we call the createToolBar() function, passing our Desc class instance, and storing the result in the actual Toolbar class:

QuickGUI::ToolBar* tb = mGUIManager->getActiveSheet()->createToolBar(tbd);

As of v9.03 and onward, there are also convenience methods so that ToolBars can be created without using the Desc object. In General, using the Desc object allows users to configure the Widget's properties before creation, instead of creating the Widget using default values, and then customizing it afterward. For example, we can also create a ToolBar with the same properties listed above, with the following code:

QuickGUI::ToolBar* tb = mGUIManager->getActiveSheet()->createToolBar(Rect(0,0,800,20));
  tb->setName("TestToolBar");

You should now have a horizontal bar across the top of your window.

Creating root menu items

Now that we have a toolbar, we can start attaching root menu items to it. Due to the limited nature of Menu's and MenuItems, they are not created using a Desc. For example, Menu's do not allow users to set their position, size, visibility, etc. As QuickGUI implements more complex Widgets, you will find a lot of Widgets are mostly managed by other widgets. Examples of this are: MenuItems, TreeViewNodes, ListItems. By using Widget::isPositionManaged and Widget::isSizeManaged, you can see if a particular widget is being managed by another.

So how do we create Menu's, if we can't use a Desc? The ToolBar API has methods that allow easy creation. Let's create the 'File' menu:

QuickGUI::Menu* f1 = tb->createMenu("File");

The previous line of code creates a Menu with the text "File". The text is set to the default color and font, as stored in the QuickGUI::Root class. The text can be changed before and after creation, using the provided APIs. Here is an example:

std::vector<TextSegment> segments;
  segments.push_back(QuickGUI::TextSegment("micross.12",QuickGUI::ColourValue::Black,"File");
  QuickGUI::Menu* f1 = tb->createMenu(segments);

And another:

QuickGUI::Menu* f1 = tb->createMenu();
  f1->setText("File");
  f1->setFont("micross.12");
  f1->setTextColor(QuickGUI::ColourValue::Black);

If you build and run the app, you will see a menu using the font micross, color (black) and the text "File".

Another item to note is the QuickGUI::Menu* f1 variable we've defined. This now holds a pointer to the menu we created, and will be used later to create submenus and define actions.

Let's create a few more of these:

segments.clear();
  segments.push_back(QuickGUI::TextSegment("micross.12",QuickGUI::ColourValue::Black,"Edit"));
  QuickGUI::Menu* m1 = tb->createMenu(segments);

  segments.clear();
  segments.push_back(QuickGUI::TextSegment("micross.12",QuickGUI::ColourValue::Black,"Format"));
  QuickGUI::Menu* m1 = tb->createMenu(segments);

Creating Submenus



Now, let's create some submenus. Submenus exist below the main menus, as well as below other submenus. They consist of items like "New", "Open", etc. Let's create a submenu under 'Format':

segments.clear();
  segments.push_back(QuickGUI::TextSegment("micross.12",QuickGUI::ColourValue::Black,"Word Wrap"));
  QuickGUI::Menu* m3 = m2->createSubMenu(segments);

Here, we created a menu like normal through provided APIs, but now, we call the 'Format' menu's pointer, creating a submenu below it. You can continue stringing submenus off of other submenus using this method.

Last, let's create a Menu called 'Exit', and define an eventhandler that exits the application:

segments.clear();
  segments.push_back(QuickGUI::TextSegment("micross.12",QuickGUI::ColourValue::Black,"Exit"));
  QuickGUI::MenuTextItem* e1 = f1->createTextItem(segments);
  e1->addWidgetEventHandler(QuickGUI:: WIDGET_EVENT_MOUSE_BUTTON_UP, &Example::ExitHandler,this);

note NOTE: Its important to subscribe to the MOUSE_BUTTON_UP event, instead of the MOUSE_CLICK event, since the menu will disappear after MOUSE_BUTTON_UP, and you will never actually be able to click on the menu item.

When the "File"->"Exit" menu is clicked, QuickGUI will call the Example::ExitHandler function, which can then handle any exit code.

Conclusion

That covers the very basics of menus. To summarize our code:

QuickGUI::ToolBar* tb = mpQGUIManager->getActiveSheet()->createToolBar(Rect(0,0,800,20));
 tb->setName("TestToolBar");
 std::vector<TextSegment> segments;
 segments.push_back(QuickGUI::TextSegment("micross.12",QuickGUI::ColourValue::Black,"File");
 QuickGUI::Menu* f1 = tb->createMenu(segments);
 segments.clear();
 segments.push_back(QuickGUI::TextSegment("micross.12",Ogre::ColourValue::Black,"Edit"));
 QuickGUI::Menu* m1 = tb->createMenu(segments);
 segments.clear();
 segments.push_back(QuickGUI::TextSegment("micross.12",Ogre::ColourValue::Black,"Format"));
 QuickGUI::Menu* m1 = tb->createMenu(segments);
 segments.clear();
 segments.push_back(QuickGUI::TextSegment("micross.12",Ogre::ColourValue::Black,"Word Wrap"));
 QuickGUI::Menu* m3 = m2->createSubMenu(segments);
 segments.clear();
 segments.push_back(QuickGUI::TextSegment("micross.12",Ogre::ColourValue::Black,"Exit"));
 QuickGUI::MenuTextItem* e1 = f1->createTextItem(segments);
 e1->addWidgetEventHandler(QuickGUI:: WIDGET_EVENT_MOUSE_BUTTON_UP, &Example::ExitHandler,this);