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
customize 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.
Normally, you would use the <menubar> element to create a menu with gtkmm. However, Hildon::Window
s instead add the menu using set_menu()
. To create this
Gtk::Menu
from a Gtk::UIManager
you must use a <popup> XML item. This is demonstrated in the 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.
File: examplewindow.h
#ifndef GTKMM_EXAMPLEWINDOW_H #define GTKMM_EXAMPLEWINDOW_H #include <gtkmm.h> #include <hildonmm.h> class ExampleWindow : public Hildon::Window { public: ExampleWindow(); virtual ~ExampleWindow(); protected: //Signal handlers: virtual void on_action_file_new(); virtual void on_action_file_quit(); virtual void on_action_others(); //Child widgets: Gtk::VBox m_Box; Glib::RefPtr<Gtk::UIManager> m_refUIManager; Glib::RefPtr<Gtk::ActionGroup> m_refActionGroup; }; #endif //GTKMM_EXAMPLEWINDOW_H
File: examplewindow.cc
#include "examplewindow.h" #include <gtkmm.h> #include <iostream> ExampleWindow::ExampleWindow() { //Create actions for menus and toolbars: m_refActionGroup = Gtk::ActionGroup::create(); //File|New sub menu: m_refActionGroup->add( Gtk::Action::create("FileNewStandard", Gtk::Stock::NEW, "_New", "Create a new file"), sigc::mem_fun(*this, &ExampleWindow::on_action_file_new) ); m_refActionGroup->add( Gtk::Action::create("FileNewFoo", Gtk::Stock::NEW, "New Foo", "Create a new foo"), sigc::mem_fun(*this, &ExampleWindow::on_action_file_new) ); m_refActionGroup->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: m_refActionGroup->add( Gtk::Action::create("FileMenu", "File") ); m_refActionGroup->add( Gtk::Action::create("FileNew", Gtk::Stock::NEW) ); //Sub-menu. m_refActionGroup->add( Gtk::Action::create("FileQuit", Gtk::Stock::QUIT), sigc::mem_fun(*this, &ExampleWindow::on_action_file_quit) ); m_refUIManager = Gtk::UIManager::create(); m_refUIManager->insert_action_group(m_refActionGroup); add_accel_group(m_refUIManager->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; m_refUIManager->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* pMenu = dynamic_cast<Gtk::Menu*>(m_refUIManager->get_widget("/FileMenu")); if(pMenu) set_main_menu(*pMenu); Gtk::Toolbar* pToolbar = dynamic_cast<Gtk::Toolbar*>(m_refUIManager->get_widget("/ToolBar")); if(pToolbar) add_toolbar(*pToolbar); // TODO: bug #875 show_all(); } 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 menu item was selected." << std::endl; } void ExampleWindow::on_action_others() { std::cout << "A menu item was selected." << std::endl; }
File: main.cc
#include <hildonmm.h> #include "examplewindow.h" #include <iostream> int main(int argc, char *argv[]) { // Initialize gtkmm: Gtk::Main kit(&argc, &argv); Hildon::init(); osso_context_t* osso_context = osso_initialize("example", "0.0.1", TRUE /* deprecated parameter */, 0 /* Use default Glib main loop context */); if(!osso_context) std::cerr << "osso_initialize() failed." << std::endl; Glib::set_application_name("UIManager example"); // Create Window and set it to Program ExampleWindow window; Hildon::Program::get_instance()->add_window(window); // Begin the main application kit.run(window); osso_deinitialize(osso_context); return 0; }