There are two ways to create menus with maemomm. The Maemo Human Interface Guidelines recommend the use of Hildon::AppMenu, which provides a menu containing a number of entries as Gtk::Buttons, organised in columns if necessary. This menu can be attached to a Hildon::Program instance, and made common to the whole application, or attached to a Hildon::Window so that different menus can be used.
Gtk::Menus can be used in maemomm, but this is not recommended as of Maemo 5.
The Maemo Human Interface Guidelines recommend Hildon::AppMenu for implementing menus with maemomm. Hildon::AppMenu is derived from Gtk::Window, and can contain Gtk::Buttons as well as groups of filter buttons (Gtk::ToggleButtons and Gtk::RadioButtons).
A Gtk::Button is added to a Hildon::AppMenu with the append(), insert() or prepend() methods. A filter button is added with the add_filter() method. A list of either the "items", i.e. normal Gtk::Buttons, or the "filters", i.e. Gtk::ToggleButtons and Gtk::RadioButtons, can be retrieved with the get_items() and get_filters methods, respectively.
This example shows how to attach a Hildon::AppMenu, containing Gtk::Buttons, Gtk::RadioButtons and Gtk::ToggleButtons, to a Hildon::Program. Clicking any of the buttons sends output to the terminal.
File: examplewindow.h
#ifndef _MAEMOMM_EXAMPLEWINDOW_H
#define _MAEMOMM_EXAMPLEWINDOW_H
#include <hildonmm/window.h>
#include <hildonmm/app-menu.h>
#include <gtkmm/button.h>
#include <gtkmm/radiobutton.h>
#include <gtkmm/togglebutton.h>
#include <gtkmm/label.h>
class ExampleWindow : public Hildon::Window
{
public:
ExampleWindow();
virtual ~ExampleWindow();
private:
// Signal handlers:
void on_button1_clicked();
void on_button2_clicked();
void on_radio_toggled();
void on_toggle1_toggled();
void on_toggle2_toggled();
// Child widgets:
Hildon::AppMenu menu_;
Gtk::Button button1_;
Gtk::Button button2_;
Gtk::RadioButton radio1_;
Gtk::RadioButton radio2_;
Gtk::ToggleButton toggle1_;
Gtk::ToggleButton toggle2_;
Gtk::Label label_;
};
#endif /* _MAEMOMM_EXAMPLEWINDOW_H */
File: main.cc
#include <hildonmm.h>
#include "examplewindow.h"
int main(int argc, char *argv[])
{
Gtk::Main kit(argc, argv);
Hildon::init();
ExampleWindow window;
Hildon::Program::get_instance()->add_window(window);
kit.run(window); //Shows the window and returns when it is closed.
return 0;
}
File: examplewindow.cc
#include "examplewindow.h"
#include <hildonmm/program.h>
#include <iostream>
ExampleWindow::ExampleWindow() :
button1_("Button 1"),
button2_("Button 2"),
radio1_("Radio 1"),
radio2_("Radio 2"),
toggle1_("Toggle 1"),
toggle2_("Toggle 2"),
label_("Hildon::AppMenu example. Click window title to display menu.")
{
set_title("Hildon::AppMenu example");
Hildon::Program::get_instance()->set_common_app_menu(menu_);
// Setup radio buttons to be in one group.
radio1_.set_active();
Gtk::RadioButton::Group radio_group = radio1_.get_group();
radio2_.set_group(radio_group);
// Add buttons and filters to AppMenu.
menu_.append(button1_);
menu_.append(button2_);
menu_.add_filter(radio1_);
menu_.add_filter(radio2_);
menu_.add_filter(toggle1_);
menu_.add_filter(toggle2_);
add(label_);
// Connect signal handlers.
button1_.signal_clicked().connect(sigc::mem_fun(*this, &ExampleWindow::on_button1_clicked));
button2_.signal_clicked().connect(sigc::mem_fun(*this, &ExampleWindow::on_button2_clicked));
radio1_.signal_clicked().connect(sigc::mem_fun(*this, &ExampleWindow::on_radio_toggled));
toggle1_.signal_clicked().connect(sigc::mem_fun(*this, &ExampleWindow::on_toggle1_toggled));
toggle2_.signal_clicked().connect(sigc::mem_fun(*this, &ExampleWindow::on_toggle1_toggled));
show_all();
}
ExampleWindow::~ExampleWindow()
{
}
void ExampleWindow::on_button1_clicked()
{
std::cout << "Button 1 clicked" << std::endl;
}
void ExampleWindow::on_button2_clicked()
{
std::cout << "Button 2 clicked" << std::endl;
}
void ExampleWindow::on_radio_toggled()
{
std::cout << "Radio button toggled, current state: Radio 1=" << radio1_.get_active() << ", Radio 2=" << radio2_.get_active() << std::endl;
}
void ExampleWindow::on_toggle1_toggled()
{
std::cout << "Toggle 1 toggled, current state=" << toggle1_.get_active() << std::endl;
}
void ExampleWindow::on_toggle2_toggled()
{
std::cout << "Toggle 2 toggled, current state=" << toggle2_.get_active() << std::endl;
}
Menus in maemomm can also use gtkmm menu functions, although the menu is then attached to the
Hildon::Program/Hildon:Window and appears in the title bar. A Gtk::Menu can be created and attached
to the Hildon::Program to be used as a common menu for all Hildon::Windows that don't have their own menu.
Another way is to use a Gtk::Menu in a Hildon::Window. In this way every application window
can have a different menu.
gtkmm menus can be created either manually or using Gtk::UIManager. The Gtk::UIManager is an
action-based API used to create menus and toolbars using an XML description. We will first show the manual way and
introduce you to Gtk::UIManager in the section Menus and Toolbars using Gtk::UIManager
// In constructor of window set_main_menu(main);
This is the only line that differs from the equivalent gtkmm example program. It specifies what menu to use for the application.
This example creates a menu with a submenu. This submenu contains radio menu items and check menu item, all of which can be toggled. The last item in the menu (Close) is attached to a signal handler so that the application can also be closed from the menu.
This example also shows how to derive your own window class from Hildon::Window:
File: examplewindow.h
#ifndef _MAEMOMM_EXAMPLEWINDOW_H
#define _MAEMOMM_EXAMPLEWINDOW_H
#include <hildonmm/window.h>
#include <gtkmm.h>
class ExampleWindow : public Hildon::Window
{
public:
ExampleWindow();
virtual ~ExampleWindow();
private:
// Signal handlers:
void on_menu_radio1();
void on_menu_radio2();
void on_menu_check();
void on_menu_close();
// Child widgets:
Gtk::Menu main_;
Gtk::Menu sub_others_;
Gtk::MenuItem item_others_;
Gtk::RadioMenuItem::Group group_;
Gtk::RadioMenuItem item_radio1_;
Gtk::RadioMenuItem item_radio2_;
Gtk::CheckMenuItem item_check_;
Gtk::CheckMenuItem item_close_;
Gtk::SeparatorMenuItem item_separator_;
};
#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);
// Add example label to window.
Gtk::Label label("Menu example");
window.add(label);
label.show();
// Begin the main application.
kit.run(window);
return 0;
}
File: examplewindow.cc
#include "examplewindow.h"
#include <gtkmm.h>
#include <iostream>
ExampleWindow::ExampleWindow() :
item_others_("Others"),
item_radio1_(group_, "Radio1"),
item_radio2_(group_, "Radio2"),
item_check_("Check"),
item_close_("Close")
{
set_title("Menu example");
// Add menu items to right menus.
main_.append(item_others_);
sub_others_.append(item_radio1_);
sub_others_.append(item_radio2_);
sub_others_.append(item_separator_);
sub_others_.append(item_check_);
main_.append(item_close_);
// Add others submenu to the "Others" item.
item_others_.set_submenu(sub_others_);
main_.show_all(); //Show the main menu and all its child widgets.
set_main_menu(main_);
// Attach the callback functions to the activate signal.
item_radio1_.signal_toggled().connect(sigc::mem_fun(*this, &ExampleWindow::on_menu_radio1));
item_radio2_.signal_toggled().connect(sigc::mem_fun(*this, &ExampleWindow::on_menu_radio2));
item_check_.signal_toggled().connect(sigc::mem_fun(*this, &ExampleWindow::on_menu_check));
item_close_.signal_activate().connect(sigc::mem_fun(*this, &ExampleWindow::on_menu_close));
// Make all child widgets visible:
show_all();
}
ExampleWindow::~ExampleWindow()
{
}
void ExampleWindow::on_menu_radio1()
{
std::cout << "Menu radioitem1 toggled. Current state=" << item_radio1_.get_active() << std::endl;
}
void ExampleWindow::on_menu_radio2()
{
std::cout << "Menu radioitem2 toggled. Current state=" << item_radio2_.get_active() << std::endl;
}
void ExampleWindow::on_menu_check()
{
std::cout << "Menu chickitem toggled. Current state=" << item_check_.get_active() << std::endl;
}
void ExampleWindow::on_menu_close()
{
hide();
}
The documentation for the standard gtkmm menu API can be found in the gtkmm tutorial.