1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Robert Roebling
7 // Copyright: (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "menu.h"
20 //-----------------------------------------------------------------------------
22 //-----------------------------------------------------------------------------
24 IMPLEMENT_DYNAMIC_CLASS(wxMenuBar
,wxWindow
)
26 wxMenuBar::wxMenuBar()
28 m_needParent
= FALSE
; // hmmm
30 PreCreation( (wxWindow
*) NULL
, -1, wxDefaultPosition
, wxDefaultSize
, 0, "menu" );
32 m_menus
.DeleteContents( TRUE
);
34 m_menubar
= gtk_menu_bar_new();
36 m_widget
= GTK_WIDGET(m_menubar
);
43 void wxMenuBar::Append( wxMenu
*menu
, const wxString
&title
)
45 m_menus
.Append( menu
);
46 menu
->m_title
= title
; // ??????
50 pos
= menu
->m_title
.First( '&' );
51 if (pos
!= -1) menu
->m_title
.Remove( pos
, 1 );
55 root_menu
= gtk_menu_item_new_with_label( WXSTRINGCAST(menu
->m_title
) );
56 gtk_widget_show( root_menu
);
57 gtk_menu_item_set_submenu( GTK_MENU_ITEM(root_menu
), menu
->m_menu
);
59 gtk_menu_bar_append( GTK_MENU_BAR(m_menubar
), root_menu
);
62 static int FindMenuItemRecursive( const wxMenu
*menu
, const wxString
&menuString
, const wxString
&itemString
)
64 if (menu
->m_title
== menuString
)
66 int res
= menu
->FindItem( itemString
);
67 if (res
!= -1) return res
;
69 wxNode
*node
= menu
->m_items
.First();
72 wxMenuItem
*item
= (wxMenuItem
*)node
->Data();
73 if (item
->IsSubMenu())
74 return FindMenuItemRecursive(item
->GetSubMenu(), menuString
, itemString
);
80 int wxMenuBar::FindMenuItem( const wxString
&menuString
, const wxString
&itemString
) const
82 wxNode
*node
= m_menus
.First();
85 wxMenu
*menu
= (wxMenu
*)node
->Data();
86 int res
= FindMenuItemRecursive( menu
, menuString
, itemString
);
87 if (res
!= -1) return res
;
93 // Find a wxMenuItem using its id. Recurses down into sub-menus
94 static wxMenuItem
* FindMenuItemByIdRecursive(const wxMenu
* menu
, int id
)
96 wxMenuItem
* result
= menu
->FindItem(id
);
98 wxNode
*node
= menu
->m_items
.First();
99 while ( node
&& result
== NULL
) {
100 wxMenuItem
*item
= (wxMenuItem
*)node
->Data();
101 if ( item
->IsSubMenu() )
102 result
= FindMenuItemByIdRecursive( item
->GetSubMenu(), id
);
109 wxMenuItem
* wxMenuBar::FindMenuItemById( int id
) const
111 wxMenuItem
* result
= 0;
112 wxNode
*node
= m_menus
.First();
113 while (node
&& result
== 0)
115 wxMenu
*menu
= (wxMenu
*)node
->Data();
116 result
= FindMenuItemByIdRecursive( menu
, id
);
122 void wxMenuBar::Check( int id
, bool check
)
124 wxMenuItem
* item
= FindMenuItemById( id
);
125 if (item
) item
->Check(check
);
128 bool wxMenuBar::Checked( int id
) const
130 wxMenuItem
* item
= FindMenuItemById( id
);
131 if (item
) return item
->IsChecked();
135 void wxMenuBar::Enable( int id
, bool enable
)
137 wxMenuItem
* item
= FindMenuItemById( id
);
138 if (item
) item
->Enable(enable
);
141 bool wxMenuBar::Enabled( int id
) const
143 wxMenuItem
* item
= FindMenuItemById( id
);
144 if (item
) return item
->IsEnabled();
148 //-----------------------------------------------------------------------------
150 //-----------------------------------------------------------------------------
152 static void gtk_menu_clicked_callback( GtkWidget
*widget
, wxMenu
*menu
)
154 int id
= menu
->FindMenuIdByMenuItem(widget
);
156 wxASSERT( id
!= -1 ); // should find it!
158 if (!menu
->IsEnabled(id
)) return;
160 wxCommandEvent
event( wxEVT_COMMAND_MENU_SELECTED
, id
);
161 event
.SetEventObject( menu
);
164 if (menu
->m_callback
)
166 (void) (*(menu
->m_callback
)) (*menu
, event
);
170 if (menu
->GetEventHandler()->ProcessEvent(event
)) return;
172 wxWindow
*win
= menu
->GetInvokingWindow();
173 if (win
) win
->GetEventHandler()->ProcessEvent( event
);
176 //-----------------------------------------------------------------------------
178 //-----------------------------------------------------------------------------
180 static void gtk_menu_hilight_callback( GtkWidget
*widget
, wxMenu
*menu
)
182 int id
= menu
->FindMenuIdByMenuItem(widget
);
184 wxASSERT( id
!= -1 ); // should find it!
186 if (!menu
->IsEnabled(id
)) return;
188 wxCommandEvent
event( wxEVT_MENU_HIGHLIGHT
, id
);
189 event
.SetEventObject( menu
);
192 /* wxMSW doesn't call callback here either
193 if (menu->m_callback)
195 (void) (*(menu->m_callback)) (*menu, event);
200 if (menu
->GetEventHandler()->ProcessEvent(event
)) return;
202 wxWindow
*win
= menu
->GetInvokingWindow();
203 if (win
) win
->GetEventHandler()->ProcessEvent( event
);
206 //-----------------------------------------------------------------------------
208 //-----------------------------------------------------------------------------
210 IMPLEMENT_DYNAMIC_CLASS(wxMenuItem
,wxObject
)
212 wxMenuItem::wxMenuItem()
215 m_isCheckMenu
= FALSE
;
218 m_subMenu
= (wxMenu
*) NULL
;
219 m_menuItem
= (GtkWidget
*) NULL
;
222 void wxMenuItem::SetText(const wxString
& str
)
225 for ( const char *pc
= str
; *pc
!= '\0'; pc
++ ) {
233 void wxMenuItem::Check( bool check
)
235 wxCHECK_RET( IsCheckable(), "Can't check uncheckable item!" )
238 gtk_check_menu_item_set_state( (GtkCheckMenuItem
*)m_menuItem
, (gint
)check
);
241 void wxMenuItem::Enable( bool enable
)
243 gtk_widget_set_sensitive( m_menuItem
, enable
);
244 m_isEnabled
= enable
;
247 bool wxMenuItem::IsChecked() const
249 wxCHECK( IsCheckable(), FALSE
); // can't get state of uncheckable item!
251 bool bIsChecked
= ((GtkCheckMenuItem
*)m_menuItem
)->active
!= 0;
253 wxASSERT( bIsChecked
== m_isChecked
); // consistency check
258 IMPLEMENT_DYNAMIC_CLASS(wxMenu
,wxEvtHandler
)
260 wxMenu::wxMenu( const wxString
& title
, const wxFunction func
)
263 m_items
.DeleteContents( TRUE
);
264 m_invokingWindow
= (wxWindow
*) NULL
;
265 m_menu
= gtk_menu_new(); // Do not show!
267 m_eventHandler
= this;
268 if (m_title
.IsNull()) m_title
= "";
276 void wxMenu::SetTitle( const wxString
& title
)
278 // Waiting for something better.
282 const wxString
wxMenu::GetTitle() const
287 void wxMenu::AppendSeparator()
289 wxMenuItem
*mitem
= new wxMenuItem();
290 mitem
->SetId(ID_SEPARATOR
);
292 GtkWidget
*menuItem
= gtk_menu_item_new();
293 gtk_menu_append( GTK_MENU(m_menu
), menuItem
);
294 gtk_widget_show( menuItem
);
295 mitem
->SetMenuItem(menuItem
);
296 m_items
.Append( mitem
);
299 void wxMenu::Append( int id
, const wxString
&item
, const wxString
&helpStr
, bool checkable
)
301 wxMenuItem
*mitem
= new wxMenuItem();
303 mitem
->SetText(item
);
304 mitem
->SetHelp(helpStr
);
305 mitem
->SetCheckable(checkable
);
306 const char *text
= mitem
->GetText();
307 GtkWidget
*menuItem
= checkable
? gtk_check_menu_item_new_with_label(text
)
308 : gtk_menu_item_new_with_label(text
);
310 mitem
->SetMenuItem(menuItem
);
312 gtk_signal_connect( GTK_OBJECT(menuItem
), "activate",
313 GTK_SIGNAL_FUNC(gtk_menu_clicked_callback
),
316 gtk_signal_connect( GTK_OBJECT(menuItem
), "select",
317 GTK_SIGNAL_FUNC(gtk_menu_hilight_callback
),
320 gtk_menu_append( GTK_MENU(m_menu
), menuItem
);
321 gtk_widget_show( menuItem
);
322 m_items
.Append( mitem
);
325 void wxMenu::Append( int id
, const wxString
&text
, wxMenu
*subMenu
, const wxString
&helpStr
)
327 wxMenuItem
*mitem
= new wxMenuItem();
329 mitem
->SetText(text
);
331 GtkWidget
*menuItem
= gtk_menu_item_new_with_label(mitem
->GetText());
332 mitem
->SetHelp(helpStr
);
333 mitem
->SetMenuItem(menuItem
);
334 mitem
->SetSubMenu(subMenu
);
336 gtk_menu_item_set_submenu( GTK_MENU_ITEM(menuItem
), subMenu
->m_menu
);
337 gtk_menu_append( GTK_MENU(m_menu
), menuItem
);
338 gtk_widget_show( menuItem
);
339 m_items
.Append( mitem
);
342 int wxMenu::FindItem( const wxString itemString
) const
344 wxString
s( itemString
);
348 pos
= s
.First( '&' );
349 if (pos
!= -1) s
.Remove( pos
, 1 );
352 wxNode
*node
= m_items
.First();
355 wxMenuItem
*item
= (wxMenuItem
*)node
->Data();
356 if (item
->GetText() == s
)
357 return item
->GetId();
364 void wxMenu::Enable( int id
, bool enable
)
366 wxMenuItem
*item
= FindItem(id
);
368 item
->Enable(enable
);
371 bool wxMenu::IsEnabled( int id
) const
373 wxMenuItem
*item
= FindItem(id
);
375 return item
->IsEnabled();
380 void wxMenu::Check( int id
, bool enable
)
382 wxMenuItem
*item
= FindItem(id
);
387 bool wxMenu::IsChecked( int id
) const
389 wxMenuItem
*item
= FindItem(id
);
391 return item
->IsChecked();
396 void wxMenu::SetLabel( int id
, const wxString
&label
)
398 wxMenuItem
*item
= FindItem(id
);
400 item
->SetText(label
);
403 wxString
wxMenu::GetLabel( int id
) const
405 wxMenuItem
*item
= FindItem(id
);
406 if (item
) return item
->GetText();
410 void wxMenu::SetHelpString( int id
, const wxString
& helpString
)
412 wxMenuItem
*item
= FindItem(id
);
413 if (item
) item
->SetHelp( helpString
);
416 wxString
wxMenu::GetHelpString( int id
) const
418 wxMenuItem
*item
= FindItem(id
);
419 if (item
) return item
->GetHelp();
423 int wxMenu::FindMenuIdByMenuItem( GtkWidget
*menuItem
) const
425 wxNode
*node
= m_items
.First();
428 wxMenuItem
*item
= (wxMenuItem
*)node
->Data();
429 if (item
->GetMenuItem() == menuItem
)
430 return item
->GetId();
437 wxMenuItem
*wxMenu::FindItem(int id
) const
439 wxNode
*node
= m_items
.First();
441 wxMenuItem
*item
= (wxMenuItem
*)node
->Data();
442 if ( item
->GetId() == id
)
447 wxLogDebug( "wxMenu::FindItem: item %d not found.", id
);
449 return (wxMenuItem
*) NULL
;
452 void wxMenu::SetInvokingWindow( wxWindow
*win
)
454 m_invokingWindow
= win
;
457 wxWindow
*wxMenu::GetInvokingWindow()
459 return m_invokingWindow
;