1 /* Menus
2 *
3 * There are several widgets involved in displaying menus. The
4 * GtkMenuBar widget is a horizontal menu bar, which normally appears
5 * at the top of an application. The GtkMenu widget is the actual menu
6 * that pops up. Both GtkMenuBar and GtkMenu are subclasses of
7 * GtkMenuShell; a GtkMenuShell contains menu items
8 * (GtkMenuItem). Each menu item contains text and/or images and can
9 * be selected by the user.
10 *
11 * There are several kinds of menu item, including plain GtkMenuItem,
12 * GtkCheckMenuItem which can be checked/unchecked, GtkRadioMenuItem
13 * which is a check menu item that's in a mutually exclusive group,
14 * GtkSeparatorMenuItem which is a separator bar, GtkTearoffMenuItem
15 * which allows a GtkMenu to be torn off, and GtkImageMenuItem which
16 * can place a GtkImage or other widget next to the menu text.
17 *
18 * A GtkMenuItem can have a submenu, which is simply a GtkMenu to pop
19 * up when the menu item is selected. Typically, all menu items in a menu bar
20 * have submenus.
21 *
22 * GtkUIManager provides a higher-level interface for creating menu bars
23 * and menus; while you can construct menus manually, most people don't
24 * do that. There's a separate demo for GtkUIManager.
25 *
26 */
27
28 #include "gtkmm.h"
29 #include <stdio.h>
30
31 class Example_Menus : public Gtk::Window
32 {
33 public:
34 Example_Menus();
35 virtual ~Example_Menus();
36
37 protected:
38 //signal handlers:
39 virtual void on_button_clicked();
40
41 virtual Gtk::Menu* create_menu(gint depth, bool tearoff);
42
43 //Member widgets:
44 Gtk::Frame m_Frame_Horizontal, m_Frame_Vertical;
45 Gtk::VBox m_VBox1, m_VBox_Sub1, m_VBox_Sub2;
46 Gtk::MenuBar m_MenuBar;
47 Gtk::HSeparator m_Separator;
48 Gtk::Button m_Button;
49 };
50
51 //Called by DemoWindow;
do_menus()52 Gtk::Window* do_menus()
53 {
54 return new Example_Menus();
55 }
56
Example_Menus()57 Example_Menus::Example_Menus()
58 : m_VBox_Sub1(false, 10),
59 m_VBox_Sub2(false, 10),
60 m_Button("close")
61 {
62 set_title("menus");
63 set_border_width(0);
64
65 add(m_VBox1);
66
67 m_VBox1.pack_start(m_MenuBar, Gtk::PACK_SHRINK);
68
69 {
70 //Note:: It's generally easier to use the Gtk::UIManager API.
71 Gtk::MenuItem* pMenuItem = Gtk::manage(new Gtk::MenuItem("test\nline2"));
72 pMenuItem->set_submenu( *(create_menu(2, true)) );
73 m_MenuBar.append(*pMenuItem);
74 pMenuItem->show();
75
76 pMenuItem = Gtk::manage(new Gtk::MenuItem("foo"));
77 pMenuItem->set_submenu( *(create_menu(3, true)) );
78 m_MenuBar.append(*pMenuItem);
79 pMenuItem->show();
80
81 pMenuItem = Gtk::manage(new Gtk::MenuItem("bar"));
82 pMenuItem->set_submenu( *(create_menu(4, true)) );
83 pMenuItem->set_right_justified();
84 m_MenuBar.append(*pMenuItem);
85 pMenuItem->show();
86 }
87
88
89 m_VBox_Sub1.set_border_width(10);
90 m_VBox1.pack_start(m_VBox_Sub1);
91
92 {
93 Gtk::Menu* pMenu = create_menu(1, false);
94 pMenu->set_accel_group(get_accel_group());
95
96 Gtk::MenuItem* pMenuItem = Gtk::manage(new Gtk::SeparatorMenuItem());
97 pMenu->append(*pMenuItem);
98 pMenuItem->show();
99
100 pMenuItem = Gtk::manage(new Gtk::CheckMenuItem("Accelerate Me"));
101 pMenuItem->add_accelerator("activate", get_accel_group(), GDK_KEY_F1, Gdk::ModifierType(0), Gtk::ACCEL_VISIBLE );
102 pMenu->append(*pMenuItem);
103 pMenuItem->show();
104
105 pMenuItem = Gtk::manage(new Gtk::CheckMenuItem("Accelerator Locked"));
106 pMenu->append(*pMenuItem);
107 pMenuItem->add_accelerator("activate", get_accel_group(), GDK_KEY_F2, Gdk::ModifierType(0), Gtk::ACCEL_VISIBLE | Gtk::ACCEL_LOCKED);
108 pMenuItem->show();
109
110 pMenuItem = Gtk::manage(new Gtk::CheckMenuItem("Accelerator Frozen"));
111 pMenu->append(*pMenuItem);
112 pMenuItem->add_accelerator("activate", get_accel_group(), GDK_KEY_F2, Gdk::ModifierType(0), Gtk::ACCEL_VISIBLE);
113 pMenuItem->show();
114 }
115
116 m_VBox1.pack_start(m_Separator, Gtk::PACK_SHRINK);
117
118
119 m_VBox_Sub2.set_border_width(10);
120 m_VBox1.pack_start(m_VBox_Sub2, Gtk::PACK_SHRINK);
121
122 m_Button.signal_clicked().connect(sigc::mem_fun(*this, &Example_Menus::on_button_clicked));
123
124 m_VBox_Sub2.pack_start(m_Button);
125 m_Button.property_can_default() = true;
126 m_Button.grab_default();
127
128 show_all();
129 }
130
~Example_Menus()131 Example_Menus::~Example_Menus()
132 {
133 }
134
create_menu(gint depth,bool tearoff)135 Gtk::Menu* Example_Menus::create_menu(gint depth, bool tearoff)
136 {
137 if (depth < 1)
138 return 0;
139
140 Gtk::Menu* pMenu = Gtk::manage(new Gtk::Menu());
141
142 {
143 if(tearoff)
144 {
145 Gtk::MenuItem* menu_item = Gtk::manage(new Gtk::TearoffMenuItem());
146 pMenu->append(*menu_item);
147 menu_item->show();
148 }
149
150 Gtk::RadioMenuItem::Group radiogroup;
151
152 for(int i = 0, j = 1; i < 5; i++, j++)
153 {
154 char buf[32];
155 sprintf(buf, "item %2d - %d", depth, j);
156
157 Gtk::MenuItem* pMenuItem = Gtk::manage(new Gtk::RadioMenuItem(radiogroup, buf));
158 pMenu->append(*pMenuItem);
159 pMenuItem->show();
160
161 if(i == 3)
162 pMenuItem->set_sensitive(false);
163
164 Gtk::Menu* pSubMenu = create_menu(depth - 1, true);
165 if(pSubMenu)
166 pMenuItem->set_submenu(*pSubMenu);
167 }
168 }
169
170 return pMenu;
171 }
172
on_button_clicked()173 void Example_Menus::on_button_clicked()
174 {
175 hide();
176 }
177