]> git.saurik.com Git - wxWidgets.git/blob - src/gtk/menu.cpp
mdi private menus
[wxWidgets.git] / src / gtk / menu.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: menu.cpp
3 // Purpose:
4 // Author: Robert Roebling
5 // Created: 01/02/97
6 // Id:
7 // Copyright: (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
11
12 #ifdef __GNUG__
13 #pragma implementation "menu.h"
14 #endif
15
16 #include "wx/menu.h"
17
18 //-----------------------------------------------------------------------------
19 // wxMenuBar
20 //-----------------------------------------------------------------------------
21
22 IMPLEMENT_DYNAMIC_CLASS(wxMenuBar,wxWindow)
23
24 wxMenuBar::wxMenuBar(void)
25 {
26 m_needParent = FALSE; // hmmm
27
28 PreCreation( NULL, -1, wxDefaultPosition, wxDefaultSize, 0, "menu" );
29
30 m_menus.DeleteContents( TRUE );
31
32 m_widget = gtk_handle_box_new();
33
34 m_menubar = gtk_menu_bar_new();
35
36 gtk_container_add( GTK_CONTAINER(m_widget), m_menubar );
37
38 gtk_widget_show( m_menubar );
39
40 PostCreation();
41
42 Show( TRUE );
43 };
44
45 void wxMenuBar::Append( wxMenu *menu, const wxString &title )
46 {
47 m_menus.Append( menu );
48 menu->m_title = title; // ??????
49
50 size_t pos;
51 do {
52 pos = menu->m_title.First( '&' );
53 if (pos != wxString::npos) menu->m_title.Remove( pos, 1 );
54 } while (pos != wxString::npos);
55
56 GtkWidget *root_menu;
57 root_menu = gtk_menu_item_new_with_label( WXSTRINGCAST(menu->m_title) );
58 gtk_widget_show( root_menu );
59 gtk_menu_item_set_submenu( GTK_MENU_ITEM(root_menu), menu->m_menu );
60
61 gtk_menu_bar_append( GTK_MENU_BAR(m_menubar), root_menu );
62 };
63
64 static int FindMenuItemRecursive( const wxMenu *menu, const wxString &menuString, const wxString &itemString )
65 {
66 if (menu->m_title == menuString)
67 {
68 int res = menu->FindItem( itemString );
69 if (res != -1) return res;
70 };
71 wxNode *node = menu->m_items.First();
72 while (node)
73 {
74 wxMenuItem *item = (wxMenuItem*)node->Data();
75 if (item->m_subMenu) return FindMenuItemRecursive( item->m_subMenu, menuString, itemString );
76 node = node->Next();
77 };
78 return -1;
79 };
80
81 int wxMenuBar::FindMenuItem( const wxString &menuString, const wxString &itemString ) const
82 {
83 wxNode *node = m_menus.First();
84 while (node)
85 {
86 wxMenu *menu = (wxMenu*)node->Data();
87 int res = FindMenuItemRecursive( menu, menuString, itemString);
88 if (res != -1) return res;
89 node = node->Next();
90 };
91 return -1;
92 };
93
94 // Find a wxMenuItem using its id. Recurses down into sub-menus
95 static wxMenuItem* FindMenuItemByIdRecursive( const wxMenu* menu, int id )
96 {
97 wxMenuItem* result = menu->FindItemForId( id );
98
99 wxNode *node = menu->m_items.First();
100 while (node && result == 0)
101 {
102 wxMenuItem *item = (wxMenuItem*)node->Data();
103 if (item->m_subMenu) result = FindMenuItemByIdRecursive( item->m_subMenu, id );
104 node = node->Next();
105 };
106 return result;
107 };
108
109 wxMenuItem* wxMenuBar::FindMenuItemById( int id ) const
110 {
111 wxMenuItem* result = 0;
112 wxNode *node = m_menus.First();
113 while (node && result == 0)
114 {
115 wxMenu *menu = (wxMenu*)node->Data();
116 result = FindMenuItemByIdRecursive( menu, id );
117 node = node->Next();
118 }
119 return result;
120 }
121
122 bool wxMenuBar::IsChecked( int id ) const
123 {
124 wxMenuItem* item = FindMenuItemById( id );
125 if (item) return item->IsChecked();
126 return FALSE;
127 }
128
129 bool wxMenuBar::IsEnabled( int id ) const
130 {
131 wxMenuItem* item = FindMenuItemById( id );
132 if (item) return item->IsEnabled();
133 return FALSE;
134 }
135
136 //-----------------------------------------------------------------------------
137 // wxMenu
138 //-----------------------------------------------------------------------------
139
140 void gtk_menu_clicked_callback( GtkWidget *widget, gpointer data )
141 {
142 wxMenu *menu = (wxMenu*)data;
143 int id = menu->FindMenuIdByMenuItem(widget);
144
145 if (!menu->Enabled(id)) return;
146
147 wxCommandEvent event( wxEVENT_TYPE_MENU_COMMAND, id );
148 event.SetEventObject( menu );
149 event.SetInt(id );
150 wxWindow *win = menu->GetInvokingWindow();
151 if (win) win->ProcessEvent( event );
152 };
153
154 IMPLEMENT_DYNAMIC_CLASS(wxMenuItem,wxObject)
155
156 wxMenuItem::wxMenuItem(void)
157 {
158 m_id = 0;
159 m_text = "";
160 m_isCheckMenu = FALSE;
161 m_checked = FALSE;
162 m_isSubMenu = FALSE;
163 m_subMenu = NULL;
164 m_helpStr = "";
165 m_menuItem = NULL;
166 };
167
168 void wxMenuItem::Check( bool check )
169 {
170 if ( IsCheckable() )
171 {
172 m_checked = check;
173 gtk_check_menu_item_set_state( (GtkCheckMenuItem*)m_menuItem, (gint)check );
174 }
175 }
176
177 bool wxMenuItem::IsChecked() const
178 {
179 if ( IsCheckable() )
180 {
181 return ((GtkCheckMenuItem*)m_menuItem)->active != 0;
182 }
183 return FALSE;
184 }
185
186 void wxMenuItem::Enable( bool enable )
187 {
188 m_isEnabled = enable;
189 }
190
191 IMPLEMENT_DYNAMIC_CLASS(wxMenu,wxEvtHandler)
192
193 wxMenu::wxMenu( const wxString &title )
194 {
195 m_title = title;
196 m_items.DeleteContents( TRUE );
197 m_invokingWindow = NULL;
198 m_menu = gtk_menu_new(); // Do not show!
199 };
200
201 void wxMenu::AppendSeparator(void)
202 {
203 wxMenuItem *mitem = new wxMenuItem();
204 mitem->m_id = ID_SEPARATOR;
205 mitem->m_text = "";
206 mitem->m_helpStr = "";
207 mitem->m_isCheckMenu = FALSE;
208 mitem->m_isEnabled = TRUE;
209 mitem->m_menuItem = gtk_menu_item_new();
210 gtk_menu_append( GTK_MENU(m_menu), mitem->m_menuItem );
211 gtk_widget_show( mitem->m_menuItem );
212 m_items.Append( mitem );
213 };
214
215 void wxMenu::Append( int id, const wxString &item, const wxString &helpStr, bool checkable )
216 {
217 wxMenuItem *mitem = new wxMenuItem();
218 mitem->m_id = id;
219
220 mitem->m_text = item;
221 size_t pos;
222 do {
223 pos = mitem->m_text.First( '&' );
224 if (pos != wxString::npos) mitem->m_text.Remove( pos, 1 );
225 } while (pos != wxString::npos);
226
227 mitem->m_helpStr = helpStr;
228 mitem->m_isCheckMenu = checkable;
229 mitem->m_isEnabled = TRUE;
230 if (checkable)
231 mitem->m_menuItem = gtk_check_menu_item_new_with_label( WXSTRINGCAST(mitem->m_text) );
232 else
233 mitem->m_menuItem = gtk_menu_item_new_with_label( WXSTRINGCAST(mitem->m_text) );
234
235 gtk_signal_connect( GTK_OBJECT(mitem->m_menuItem), "activate",
236 GTK_SIGNAL_FUNC(gtk_menu_clicked_callback), (gpointer*)this );
237
238 gtk_menu_append( GTK_MENU(m_menu), mitem->m_menuItem );
239 gtk_widget_show( mitem->m_menuItem );
240 m_items.Append( mitem );
241 };
242
243 void wxMenu::Append( int id, const wxString &item, wxMenu *subMenu, const wxString &helpStr )
244 {
245 wxMenuItem *mitem = new wxMenuItem();
246 mitem->m_id = id;
247 mitem->m_text = item;
248 mitem->m_isEnabled = TRUE;
249
250 size_t pos;
251 do {
252 pos = mitem->m_text.First( '&' );
253 if (pos != wxString::npos) mitem->m_text.Remove( pos, 1 );
254 } while (pos != wxString::npos);
255
256 mitem->m_helpStr = helpStr;
257 mitem->m_menuItem = gtk_menu_item_new_with_label( WXSTRINGCAST(mitem->m_text) );
258
259 mitem->m_subMenu = subMenu;
260 gtk_menu_item_set_submenu( GTK_MENU_ITEM(mitem->m_menuItem), subMenu->m_menu );
261 gtk_menu_append( GTK_MENU(m_menu), mitem->m_menuItem );
262 gtk_widget_show( mitem->m_menuItem );
263 m_items.Append( mitem );
264 };
265
266 int wxMenu::FindItem( const wxString itemString ) const
267 {
268 wxString s( itemString );
269
270 size_t pos;
271 do {
272 pos = s.First( '&' );
273 if (pos != wxString::npos) s.Remove( pos, 1 );
274 } while (pos != wxString::npos);
275
276 wxNode *node = m_items.First();
277 while (node)
278 {
279 wxMenuItem *item = (wxMenuItem*)node->Data();
280 if (item->m_text == s) return item->m_id;
281 node = node->Next();
282 };
283 return -1;
284 };
285
286 wxMenuItem* wxMenu::FindItemForId( int id ) const
287 {
288 wxNode *node = m_items.First();
289 while (node)
290 {
291 wxMenuItem *item = (wxMenuItem*)node->Data();
292 if (item->m_id == id) return item;
293 node = node->Next();
294 }
295 return NULL;
296 }
297
298 void wxMenu::Check( int id, bool Flag )
299 {
300 wxMenuItem* item = FindItemForId( id );
301 if (item) item->Check(Flag);
302 };
303
304 void wxMenu::Enable( int id, bool enable )
305 {
306 wxNode *node = m_items.First();
307 while (node)
308 {
309 wxMenuItem *item = (wxMenuItem*)node->Data();
310 if (item->m_id == id)
311 {
312 item->m_isEnabled = enable;
313 return;
314 };
315 node = node->Next();
316 };
317 };
318
319 bool wxMenu::Enabled( int id ) const
320 {
321 wxNode *node = m_items.First();
322 while (node)
323 {
324 wxMenuItem *item = (wxMenuItem*)node->Data();
325 if (item->m_id == id) return item->m_isEnabled;
326 node = node->Next();
327 };
328 return FALSE;
329 };
330
331 void wxMenu::SetLabel( int id, const wxString &label )
332 {
333 wxString s( label );
334 size_t pos;
335 do {
336 pos = s.First( '&' );
337 if (pos != wxString::npos) s.Remove( pos, 1 );
338 } while (pos != wxString::npos);
339
340 wxNode *node = m_items.First();
341 while (node)
342 {
343 wxMenuItem *item = (wxMenuItem*)node->Data();
344 item->m_text = s;
345 if (item->m_id == id)
346 {
347 gtk_label_set( GTK_LABEL( GTK_BIN(item->m_menuItem)->child ), WXSTRINGCAST(s) );
348 };
349 node = node->Next();
350 };
351 };
352
353 int wxMenu::FindMenuIdByMenuItem( GtkWidget *menuItem ) const
354 {
355 wxNode *node = m_items.First();
356 while (node)
357 {
358 wxMenuItem *item = (wxMenuItem*)node->Data();
359 if (item->m_menuItem == menuItem) return item->m_id;
360 node = node->Next();
361 };
362 return -1;
363 };
364
365 void wxMenu::SetInvokingWindow( wxWindow *win )
366 {
367 m_invokingWindow = win;
368 };
369
370 wxWindow *wxMenu::GetInvokingWindow(void)
371 {
372 return m_invokingWindow;
373 };
374
375