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( NULL
, -1, wxDefaultPosition
, wxDefaultSize
, 0, "menu" );
32 m_menus
.DeleteContents( TRUE
);
34 m_widget
= gtk_handle_box_new();
36 m_menubar
= gtk_menu_bar_new();
38 gtk_container_add( GTK_CONTAINER(m_widget
), m_menubar
);
40 gtk_widget_show( m_menubar
);
47 void wxMenuBar::Append( wxMenu
*menu
, const wxString
&title
)
49 m_menus
.Append( menu
);
50 menu
->m_title
= title
; // ??????
54 pos
= menu
->m_title
.First( '&' );
55 if (pos
!= -1) menu
->m_title
.Remove( pos
, 1 );
59 root_menu
= gtk_menu_item_new_with_label( WXSTRINGCAST(menu
->m_title
) );
60 gtk_widget_show( root_menu
);
61 gtk_menu_item_set_submenu( GTK_MENU_ITEM(root_menu
), menu
->m_menu
);
63 gtk_menu_bar_append( GTK_MENU_BAR(m_menubar
), root_menu
);
66 static int FindMenuItemRecursive( const wxMenu
*menu
, const wxString
&menuString
, const wxString
&itemString
)
68 if (menu
->m_title
== menuString
)
70 int res
= menu
->FindItem( itemString
);
71 if (res
!= -1) return res
;
73 wxNode
*node
= menu
->m_items
.First();
76 wxMenuItem
*item
= (wxMenuItem
*)node
->Data();
77 if (item
->IsSubMenu())
78 return FindMenuItemRecursive(item
->GetSubMenu(), menuString
, itemString
);
84 int wxMenuBar::FindMenuItem( const wxString
&menuString
, const wxString
&itemString
) const
86 wxNode
*node
= m_menus
.First();
89 wxMenu
*menu
= (wxMenu
*)node
->Data();
90 int res
= FindMenuItemRecursive( menu
, menuString
, itemString
);
91 if (res
!= -1) return res
;
97 // Find a wxMenuItem using its id. Recurses down into sub-menus
98 static wxMenuItem
* FindMenuItemByIdRecursive(const wxMenu
* menu
, int id
)
100 wxMenuItem
* result
= menu
->FindItem(id
);
102 wxNode
*node
= menu
->m_items
.First();
103 while ( node
&& result
== NULL
) {
104 wxMenuItem
*item
= (wxMenuItem
*)node
->Data();
105 if ( item
->IsSubMenu() )
106 result
= FindMenuItemByIdRecursive( item
->GetSubMenu(), id
);
113 wxMenuItem
* wxMenuBar::FindMenuItemById( int id
) const
115 wxMenuItem
* result
= 0;
116 wxNode
*node
= m_menus
.First();
117 while (node
&& result
== 0)
119 wxMenu
*menu
= (wxMenu
*)node
->Data();
120 result
= FindMenuItemByIdRecursive( menu
, id
);
126 void wxMenuBar::Check( int id
, bool check
)
128 wxMenuItem
* item
= FindMenuItemById( id
);
129 if (item
) item
->Check(check
);
132 bool wxMenuBar::Checked( int id
) const
134 wxMenuItem
* item
= FindMenuItemById( id
);
135 if (item
) return item
->IsChecked();
139 void wxMenuBar::Enable( int id
, bool enable
)
141 wxMenuItem
* item
= FindMenuItemById( id
);
142 if (item
) item
->Enable(enable
);
145 bool wxMenuBar::Enabled( int id
) const
147 wxMenuItem
* item
= FindMenuItemById( id
);
148 if (item
) return item
->IsEnabled();
152 //-----------------------------------------------------------------------------
154 //-----------------------------------------------------------------------------
156 static void gtk_menu_clicked_callback( GtkWidget
*widget
, wxMenu
*menu
)
158 int id
= menu
->FindMenuIdByMenuItem(widget
);
160 wxASSERT( id
!= -1 ); // should find it!
162 if (!menu
->IsEnabled(id
)) return;
164 wxCommandEvent
event( wxEVENT_TYPE_MENU_COMMAND
, id
);
165 event
.SetEventObject( menu
);
168 if (menu
->m_callback
)
170 (void) (*(menu
->m_callback
)) (*menu
, event
);
174 if (menu
->GetEventHandler()->ProcessEvent(event
)) return;
176 wxWindow
*win
= menu
->GetInvokingWindow();
177 if (win
) win
->GetEventHandler()->ProcessEvent( event
);
180 IMPLEMENT_DYNAMIC_CLASS(wxMenuItem
,wxObject
)
182 wxMenuItem::wxMenuItem()
185 m_isCheckMenu
= FALSE
;
192 void wxMenuItem::SetText(const wxString
& str
)
195 for ( const char *pc
= str
; *pc
!= '\0'; pc
++ ) {
203 void wxMenuItem::Check( bool check
)
205 wxCHECK_RET( IsCheckable(), _("Can't check uncheckable item!") )
208 gtk_check_menu_item_set_state( (GtkCheckMenuItem
*)m_menuItem
, (gint
)check
);
211 void wxMenuItem::Enable( bool enable
)
213 gtk_widget_set_sensitive( m_menuItem
, enable
);
214 m_isEnabled
= enable
;
217 bool wxMenuItem::IsChecked() const
219 wxCHECK( IsCheckable(), FALSE
); // can't get state of uncheckable item!
221 bool bIsChecked
= ((GtkCheckMenuItem
*)m_menuItem
)->active
!= 0;
223 wxASSERT( bIsChecked
== m_isChecked
); // consistency check
228 IMPLEMENT_DYNAMIC_CLASS(wxMenu
,wxEvtHandler
)
230 wxMenu::wxMenu( const wxString
& title
, const wxFunction func
)
233 m_items
.DeleteContents( TRUE
);
234 m_invokingWindow
= NULL
;
235 m_menu
= gtk_menu_new(); // Do not show!
237 m_eventHandler
= this;
238 if (m_title
.IsNull()) m_title
= "";
246 void wxMenu::SetTitle( const wxString
& title
)
248 // Waiting for something better.
252 const wxString
wxMenu::GetTitle() const
257 void wxMenu::AppendSeparator()
259 wxMenuItem
*mitem
= new wxMenuItem();
260 mitem
->SetId(ID_SEPARATOR
);
262 GtkWidget
*menuItem
= gtk_menu_item_new();
263 gtk_menu_append( GTK_MENU(m_menu
), menuItem
);
264 gtk_widget_show( menuItem
);
265 mitem
->SetMenuItem(menuItem
);
266 m_items
.Append( mitem
);
269 void wxMenu::Append( int id
, const wxString
&item
, const wxString
&helpStr
, bool checkable
)
271 wxMenuItem
*mitem
= new wxMenuItem();
273 mitem
->SetText(item
);
274 mitem
->SetHelp(helpStr
);
275 mitem
->SetCheckable(checkable
);
276 const char *text
= mitem
->GetText();
277 GtkWidget
*menuItem
= checkable
? gtk_check_menu_item_new_with_label(text
)
278 : gtk_menu_item_new_with_label(text
);
280 mitem
->SetMenuItem(menuItem
);
282 gtk_signal_connect( GTK_OBJECT(menuItem
), "activate",
283 GTK_SIGNAL_FUNC(gtk_menu_clicked_callback
),
286 gtk_menu_append( GTK_MENU(m_menu
), menuItem
);
287 gtk_widget_show( menuItem
);
288 m_items
.Append( mitem
);
291 void wxMenu::Append( int id
, const wxString
&text
, wxMenu
*subMenu
, const wxString
&helpStr
)
293 wxMenuItem
*mitem
= new wxMenuItem();
295 mitem
->SetText(text
);
297 GtkWidget
*menuItem
= gtk_menu_item_new_with_label(mitem
->GetText());
298 mitem
->SetHelp(helpStr
);
299 mitem
->SetMenuItem(menuItem
);
300 mitem
->SetSubMenu(subMenu
);
302 gtk_menu_item_set_submenu( GTK_MENU_ITEM(menuItem
), subMenu
->m_menu
);
303 gtk_menu_append( GTK_MENU(m_menu
), menuItem
);
304 gtk_widget_show( menuItem
);
305 m_items
.Append( mitem
);
308 int wxMenu::FindItem( const wxString itemString
) const
310 wxString
s( itemString
);
314 pos
= s
.First( '&' );
315 if (pos
!= -1) s
.Remove( pos
, 1 );
318 wxNode
*node
= m_items
.First();
321 wxMenuItem
*item
= (wxMenuItem
*)node
->Data();
322 if (item
->GetText() == s
)
323 return item
->GetId();
330 void wxMenu::Enable( int id
, bool enable
)
332 wxMenuItem
*item
= FindItem(id
);
334 item
->Enable(enable
);
337 bool wxMenu::IsEnabled( int id
) const
339 wxMenuItem
*item
= FindItem(id
);
341 return item
->IsEnabled();
346 void wxMenu::Check( int id
, bool enable
)
348 wxMenuItem
*item
= FindItem(id
);
353 bool wxMenu::IsChecked( int id
) const
355 wxMenuItem
*item
= FindItem(id
);
357 return item
->IsChecked();
362 void wxMenu::SetLabel( int id
, const wxString
&label
)
364 wxMenuItem
*item
= FindItem(id
);
366 item
->SetText(label
);
369 wxString
wxMenu::GetLabel( int id
) const
371 wxMenuItem
*item
= FindItem(id
);
372 if (item
) return item
->GetText();
376 void wxMenu::SetHelpString( int id
, const wxString
& helpString
)
378 wxMenuItem
*item
= FindItem(id
);
379 if (item
) item
->SetHelp( helpString
);
382 wxString
wxMenu::GetHelpString( int id
) const
384 wxMenuItem
*item
= FindItem(id
);
385 if (item
) return item
->GetHelp();
389 int wxMenu::FindMenuIdByMenuItem( GtkWidget
*menuItem
) const
391 wxNode
*node
= m_items
.First();
394 wxMenuItem
*item
= (wxMenuItem
*)node
->Data();
395 if (item
->GetMenuItem() == menuItem
)
396 return item
->GetId();
403 wxMenuItem
*wxMenu::FindItem(int id
) const
405 wxNode
*node
= m_items
.First();
407 wxMenuItem
*item
= (wxMenuItem
*)node
->Data();
408 if ( item
->GetId() == id
)
413 wxLogDebug(_("wxMenu::FindItem: item %d not found."), id
);
418 void wxMenu::SetInvokingWindow( wxWindow
*win
)
420 m_invokingWindow
= win
;
423 wxWindow
*wxMenu::GetInvokingWindow()
425 return m_invokingWindow
;