Examples
| Chapter 11. Menus and Toolbars |

## Examples

### Main Menu example

Figure 11.1. Main Menu

Source Code

File: `examplewindow.h`

    #ifndef GTKMM_EXAMPLEWINDOW_H
    #define GTKMM_EXAMPLEWINDOW_H

    #include <gtkmm/window.h>
    #include <gtkmm/box.h>
    #include <gtkmm/uimanager.h>
    #include <gtkmm/radioaction.h>

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

    protected:
      //Signal handlers:
      virtual void on_menu_file_new_generic();
      virtual void on_menu_file_quit();
      virtual void on_menu_others();

      virtual void on_menu_choices_one();
      virtual void on_menu_choices_two();

      //Child widgets:
      Gtk::VBox m_Box;

      Glib::RefPtr<Gtk::UIManager> m_refUIManager;
      Glib::RefPtr<Gtk::ActionGroup> m_refActionGroup;
      Glib::RefPtr<Gtk::RadioAction> m_refChoiceOne, m_refChoiceTwo;
    };

    #endif //GTKMM_EXAMPLEWINDOW_H

File: `examplewindow.cc`

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

    ExampleWindow::ExampleWindow()
    {
      set_title("main menu example");
      set_default_size(200, 200);

      add(m_Box); //We can put a MenuBar at the top of the box and other stuff below it.

      //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_menu_file_new_generic) );

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

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

      //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_menu_file_quit) );

      //Edit menu:
      m_refActionGroup->add( Gtk::Action::create("EditMenu", "Edit") );
      m_refActionGroup->add( Gtk::Action::create("EditCopy", Gtk::Stock::COPY),
        sigc::mem_fun(*this, &ExampleWindow::on_menu_others) );
      m_refActionGroup->add( Gtk::Action::create("EditPaste", Gtk::Stock::PASTE),
        sigc::mem_fun(*this, &ExampleWindow::on_menu_others) );
      m_refActionGroup->add( Gtk::Action::create("EditSomething", "Something"), Gtk::AccelKey("<control><alt>S"),
        sigc::mem_fun(*this, &ExampleWindow::on_menu_others) );

      //Choices menu, to demonstrate Radio items
      m_refActionGroup->add( Gtk::Action::create("ChoicesMenu", "Choices") );
      Gtk::RadioAction::Group group_userlevel;
      m_refChoiceOne = Gtk::RadioAction::create(group_userlevel, "ChoiceOne", "One");
      m_refActionGroup->add(m_refChoiceOne,
        sigc::mem_fun(*this, &ExampleWindow::on_menu_choices_one) );
      m_refChoiceTwo = Gtk::RadioAction::create(group_userlevel, "ChoiceTwo", "Two");
      m_refActionGroup->add(m_refChoiceTwo,
        sigc::mem_fun(*this, &ExampleWindow::on_menu_choices_two) );

      //Help menu:
      m_refActionGroup->add( Gtk::Action::create("HelpMenu", "Help") );
      m_refActionGroup->add( Gtk::Action::create("HelpAbout", Gtk::Stock::HELP),
        sigc::mem_fun(*this, &ExampleWindow::on_menu_others) );

      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 menubar and toolbar:

      Glib::ustring ui_info =
            "<ui>"
            "  <menubar name='MenuBar'>"
            "    <menu action='FileMenu'>"
            "      <menu action='FileNew'>"
            "        <menuitem action='FileNewStandard'/>"
            "        <menuitem action='FileNewFoo'/>"
            "        <menuitem action='FileNewGoo'/>"
            "      </menu>"
            "      <separator/>"
            "      <menuitem action='FileQuit'/>"
            "    </menu>"
            "    <menu action='EditMenu'>"
            "      <menuitem action='EditCopy'/>"
            "      <menuitem action='EditPaste'/>"
            "      <menuitem action='EditSomething'/>"
            "    </menu>"
            "    <menu action='ChoicesMenu'>"
            "      <menuitem action='ChoiceOne'/>"
            "      <menuitem action='ChoiceTwo'/>"
            "    </menu>"
            "    <menu action='HelpMenu'>"
            "      <menuitem action='HelpAbout'/>"
            "    </menu>"
            "  </menubar>"
            "  <toolbar  name='ToolBar'>"
            "    <toolitem action='FileNewStandard'/>"
            "    <toolitem action='FileQuit'/>"
            "  </toolbar>"
            "</ui>";

      #ifdef GLIBMM_EXCEPTIONS_ENABLED
      try
      {
        m_refUIManager->add_ui_from_string(ui_info);
      }
      catch(const Glib::Error& ex)
      {
        std::cerr << "building menus failed: " <<  ex.what();
      }
      #else
      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();
      }
      #endif //GLIBMM_EXCEPTIONS_ENABLED

      //Get the menubar and toolbar widgets, and add them to a container widget:
      Gtk::Widget* pMenubar = m_refUIManager->get_widget("/MenuBar");
      if(pMenubar)
        m_Box.pack_start(*pMenubar, Gtk::PACK_SHRINK);

      Gtk::Widget* pToolbar = m_refUIManager->get_widget("/ToolBar") ;
      if(pToolbar)
        m_Box.pack_start(*pToolbar, Gtk::PACK_SHRINK);

      show_all_children();
    }

    ExampleWindow::~ExampleWindow()
    {
    }

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

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

    void ExampleWindow::on_menu_others()
    {
      std::cout << "A menu item was selected." << std::endl;
    }

    void ExampleWindow::on_menu_choices_one()
    {
      Glib::ustring message;
      if(m_refChoiceOne->get_active())
        message = "Choice 1 was selected.";
      else
        message = "Choice 1 was deselected";

      std::cout << message << std::endl;
    }

    void ExampleWindow::on_menu_choices_two()
    {
      Glib::ustring message;
      if(m_refChoiceTwo->get_active())
        message = "Choice 2 was selected.";
      else
        message = "Choice 2 was deselected";

      std::cout << message << std::endl;
    }

File: `main.cc`

    #include <gtkmm/main.h>
    #include "examplewindow.h"

    int main(int argc, char *argv[])
    {
      Gtk::Main kit(argc, argv);

      ExampleWindow window;
      Gtk::Main::run(window); //Shows the window and returns when it is closed.

      return 0;
    }

### Popup Menu example

Figure 11.2. Popup Menu

Source Code

File: `examplewindow.h`

    #ifndef GTKMM_EXAMPLEWINDOW_H
    #define GTKMM_EXAMPLEWINDOW_H

    #include <gtkmm/window.h>
    #include <gtkmm/box.h>
    #include <gtkmm/eventbox.h>
    #include <gtkmm/label.h>
    #include <gtkmm/uimanager.h>
    #include <gtkmm/menu.h>

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

    protected:
      //Signal handlers:
      virtual bool on_button_press_event(GdkEventButton* event);
      virtual void on_menu_file_popup_generic();

      //Child widgets:
      Gtk::VBox m_Box;
      Gtk::EventBox m_EventBox;
      Gtk::Label m_Label;

      Glib::RefPtr<Gtk::UIManager> m_refUIManager;
      Glib::RefPtr<Gtk::ActionGroup> m_refActionGroup;

      Gtk::Menu* m_pMenuPopup;
    };

    #endif //GTKMM_EXAMPLEWINDOW_H

File: `examplewindow.cc`

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

    ExampleWindow::ExampleWindow()
    : m_Label("Right-click to see the popup menu."),
      m_pMenuPopup(0)
      /* m_Image(Gtk::Stock::DIALOG_QUESTION, Gtk::ICON_SIZE_MENU) */
    {
      set_title("popup example");
      set_default_size(200, 200);

      add(m_Box);

      //Add an event box that can catch button_press events:
      m_Box.pack_start(m_EventBox);
      m_EventBox.signal_button_press_event().connect( sigc::mem_fun(*this, &ExampleWindow::on_button_press_event) );

      m_EventBox.add(m_Label);

      //Create actions:

      //Fill menu:

      m_refActionGroup = Gtk::ActionGroup::create();

      //File|New sub menu:
      //These menu actions would normally already exist for a main menu, because a context menu
      //should not normally contain menu items that are only available via a context menu.
      m_refActionGroup->add( Gtk::Action::create("ContextMenu", "Context Menu") );

      m_refActionGroup->add( Gtk::Action::create("ContextEdit", "Edit"),
        sigc::mem_fun(*this, &ExampleWindow::on_menu_file_popup_generic) );

      m_refActionGroup->add( Gtk::Action::create("ContextProcess", "Process"), Gtk::AccelKey("<control>P"),
        sigc::mem_fun(*this, &ExampleWindow::on_menu_file_popup_generic) );

      m_refActionGroup->add( Gtk::Action::create("ContextRemove", "Remove"),
        sigc::mem_fun(*this, &ExampleWindow::on_menu_file_popup_generic) );

      //TODO:
      /*
        //Add a ImageMenuElem:
        menulist.push_back( Gtk::Menu_Helpers::ImageMenuElem("_Something", m_Image,
          sigc::mem_fun(*this, &ExampleWindow::on_menu_file_popup_generic) ) ) ;
      */

      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 menubar and toolbar:
      Glib::ustring ui_info =
            "<ui>"
            "  <popup name='PopupMenu'>"
            "    <menuitem action='ContextEdit'/>"
            "    <menuitem action='ContextProcess'/>"
            "    <menuitem action='ContextRemove'/>"
            "  </popup>"
            "</ui>";

      #ifdef GLIBMM_EXCEPTIONS_ENABLED
      try
      {
        m_refUIManager->add_ui_from_string(ui_info);
      }
      catch(const Glib::Error& ex)
      {
        std::cerr << "building menus failed: " <<  ex.what();
      }
      #else
      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();
      }
      #endif //GLIBMM_EXCEPTIONS_ENABLED

      //Get the menu:
      m_pMenuPopup = dynamic_cast<Gtk::Menu*>( m_refUIManager->get_widget("/PopupMenu") );
      if(!m_pMenuPopup)
        g_warning("menu not found");

      show_all_children();
    }

    ExampleWindow::~ExampleWindow()
    {
    }

    void ExampleWindow::on_menu_file_popup_generic()
    {
       std::cout << "A popup menu item was selected." << std::endl;
    }

    bool ExampleWindow::on_button_press_event(GdkEventButton* event)
    {
      if( (event->type == GDK_BUTTON_PRESS) && (event->button == 3) )
      {
        if(m_pMenuPopup)
          m_pMenuPopup->popup(event->button, event->time);

        return true; //It has been handled.
      }
      else
        return false;
    }

File: `main.cc`

    #include <gtkmm/main.h>
    #include "examplewindow.h"

    int main(int argc, char *argv[])
    {
      Gtk::Main kit(argc, argv);

      ExampleWindow window;
      Gtk::Main::run(window); //Shows the window and returns when it is closed.

      return 0;
    }

Popup Menus |  | Chapter 12. Adjustments