Menus and Toolbars using Gtk::UIManager

Instead of creating menus and toolbars by hand you can also do this using the action-based API, with an XML description. This is the preferred way because it makes it much easier to customise the UI of an application and allows you to handle user actions regardless of whether they are initiated from a menu item or toolbar button. The use of Gtk::UIManager with maemomm does not differ much from gtkmm.

[Note] Note

You may not use Gtk::UIManager to create a Hildon::EditToolbar or Hildon::FindToolbar. Additionally, the use of Gtk::Menu is discouraged for Maemo 5.

Normally, you would use the <menubar> element to create a menu with gtkmm. However, Hildon::Windows instead add the menu using set_menu(). To create this Gtk::Menu from a Gtk::UIManager you must use a <popup> XML item. The example demonstrates this.

Reference

Example

This example shows how to use the Gtk::UIManager with a Hildon::Window. See the Gtk::UIManager section of the gtkmm tutorial for a fuller explanation.

Figure 4.18. Menus and toolbars with UIManager

Menus and toolbars with UIManager

Source Code

File: examplewindow.h

#ifndef _MAEMOMM_EXAMPLEWINDOW_H
#define _MAEMOMM_EXAMPLEWINDOW_H

#include <gtkmm.h>
#include <hildonmm/window.h>

class ExampleWindow : public Hildon::Window
{
public:
  ExampleWindow();
  virtual ~ExampleWindow();

private:
  // Signal handlers:
  void on_action_file_new();
  void on_action_file_quit();
  void on_action_others();

  // Child widgets:
  Gtk::VBox box_;

  Glib::RefPtr<Gtk::UIManager> uimanager_;
  Glib::RefPtr<Gtk::ActionGroup> actiongroup_;
};

#endif /* _MAEMOMM_EXAMPLEWINDOW_H */

File: main.cc

#include <hildonmm.h>
#include "examplewindow.h"

int main(int argc, char *argv[])
{
  // Initialize gtkmm:
  Gtk::Main kit(&argc, &argv);
  Hildon::init();
  
  // Create Window and set it to Program.
  ExampleWindow window;
  Hildon::Program::get_instance()->add_window(window);

  // Begin the main application.
  kit.run(window);

  return 0;

}

File: examplewindow.cc

#include "examplewindow.h"
#include <gtkmm.h>
#include <iostream>

ExampleWindow::ExampleWindow()
{
  set_title("UIManager Example");

  // Create actions for menus and toolbars:
  actiongroup_ = Gtk::ActionGroup::create();

  // File|New sub menu:
  actiongroup_->add(Gtk::Action::create("FileNewStandard", Gtk::Stock::NEW,
    "_New", "Create a new file"),
    sigc::mem_fun(*this, &ExampleWindow::on_action_file_new));

  actiongroup_->add(Gtk::Action::create("FileNewFoo", Gtk::Stock::NEW,
    "New Foo", "Create a new foo"),
    sigc::mem_fun(*this, &ExampleWindow::on_action_file_new));

  actiongroup_->add(Gtk::Action::create("FileNewGoo", Gtk::Stock::NEW, "_New Goo", "Create a new goo"),
    sigc::mem_fun(*this, &ExampleWindow::on_action_file_new));

  // File menu:
  actiongroup_->add(Gtk::Action::create("FileMenu", "File"));
  // Sub-menu.
  actiongroup_->add(Gtk::Action::create("FileNew", Gtk::Stock::NEW));
  actiongroup_->add(Gtk::Action::create("FileQuit", Gtk::Stock::QUIT),
    sigc::mem_fun(*this, &ExampleWindow::on_action_file_quit));

  uimanager_ = Gtk::UIManager::create();
  uimanager_->insert_action_group(actiongroup_);
 
  add_accel_group(uimanager_->get_accel_group());

  /* Layout the actions in a menu and toolbar. In Hildon you have to use
   *  "popup" for the menu because you can only have one menu and cannot add
   *  a whole menubar. */
  
  Glib::ustring ui_info = 
        "<ui>"
        "    <popup action='FileMenu'>"
        "      <menu action='FileNew'>"
        "        <menuitem action='FileNewStandard'/>"
        "        <menuitem action='FileNewFoo'/>"
        "        <menuitem action='FileNewGoo'/>"
        "      </menu>"
        "      <separator/>"
        "      <menuitem action='FileQuit'/>"
        "    </popup>"
        "  <toolbar  name='ToolBar'>"
        "    <toolitem action='FileNewStandard'/>"
        "    <toolitem action='FileQuit'/>"
        "  </toolbar>"
        "</ui>";

  std::auto_ptr<Glib::Error> ex;
  uimanager_->add_ui_from_string(ui_info, ex);
  if(ex.get())
  { 
    std::cerr << "building menus failed: " <<  ex->what();
  }
 
  // Get the menu and toolbar widgets, and add them to a container widget:
  Gtk::Menu* menu =
    dynamic_cast<Gtk::Menu*>(uimanager_->get_widget("/FileMenu"));
  if(menu)
    set_main_menu(*menu);

  Gtk::Toolbar* toolbar =
    dynamic_cast<Gtk::Toolbar*>(uimanager_->get_widget("/ToolBar"));
  if(toolbar)
    add_toolbar(*toolbar);
  
  show_all_children();
}

ExampleWindow::~ExampleWindow()
{
}

void ExampleWindow::on_action_file_quit()
{
  hide(); // Closes the main window to stop the Gtk::Main::run().
}

void ExampleWindow::on_action_file_new()
{
   std::cout << "A File|New action was selected." << std::endl;
}

void ExampleWindow::on_action_others()
{
  std::cout << "An action was selected." << std::endl;
}