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::Button
s, 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::Menu
s 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::Button
s as well as groups of filter buttons (Gtk::ToggleButton
s and Gtk::RadioButton
s).
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::Button
s, or the "filters", i.e. Gtk::ToggleButton
s and Gtk::RadioButton
s, can be retrieved with the get_items()
and get_filters
methods, respectively.
This example shows how to attach a Hildon::AppMenu
, containing Gtk::Button
s, Gtk::RadioButton
s and Gtk::ToggleButton
s, 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_children(); } 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::Window
s 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_children(); //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_children(); } 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.