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"
19 //-----------------------------------------------------------------------------
21 //-----------------------------------------------------------------------------
23 IMPLEMENT_DYNAMIC_CLASS(wxMenuBar
,wxWindow
)
25 wxMenuBar::wxMenuBar()
27 m_needParent
= FALSE
; // hmmm
29 PreCreation( NULL
, -1, wxDefaultPosition
, wxDefaultSize
, 0, "menu" );
31 m_menus
.DeleteContents( TRUE
);
33 m_widget
= gtk_handle_box_new();
35 m_menubar
= gtk_menu_bar_new();
37 gtk_container_add( GTK_CONTAINER(m_widget
), m_menubar
);
39 gtk_widget_show( m_menubar
);
46 void wxMenuBar::Append( wxMenu
*menu
, const wxString
&title
)
48 m_menus
.Append( menu
);
49 menu
->m_title
= title
; // ??????
53 pos
= menu
->m_title
.First( '&' );
54 if (pos
!= -1) menu
->m_title
.Remove( pos
, 1 );
58 root_menu
= gtk_menu_item_new_with_label( WXSTRINGCAST(menu
->m_title
) );
59 gtk_widget_show( root_menu
);
60 gtk_menu_item_set_submenu( GTK_MENU_ITEM(root_menu
), menu
->m_menu
);
62 gtk_menu_bar_append( GTK_MENU_BAR(m_menubar
), root_menu
);
65 static int FindMenuItemRecursive( const wxMenu
*menu
, const wxString
&menuString
, const wxString
&itemString
)
67 if (menu
->m_title
== menuString
)
69 int res
= menu
->FindItem( itemString
);
70 if (res
!= -1) return res
;
72 wxNode
*node
= menu
->m_items
.First();
75 wxMenuItem
*item
= (wxMenuItem
*)node
->Data();
76 if (item
->IsSubMenu())
77 return FindMenuItemRecursive(item
->GetSubMenu(), menuString
, itemString
);
83 int wxMenuBar::FindMenuItem( const wxString
&menuString
, const wxString
&itemString
) const
85 wxNode
*node
= m_menus
.First();
88 wxMenu
*menu
= (wxMenu
*)node
->Data();
89 int res
= FindMenuItemRecursive( menu
, menuString
, itemString
);
90 if (res
!= -1) return res
;
96 // Find a wxMenuItem using its id. Recurses down into sub-menus
97 static wxMenuItem
* FindMenuItemByIdRecursive(const wxMenu
* menu
, int id
)
99 wxMenuItem
* result
= menu
->FindItem(id
);
101 wxNode
*node
= menu
->m_items
.First();
102 while ( node
&& result
== NULL
) {
103 wxMenuItem
*item
= (wxMenuItem
*)node
->Data();
104 if ( item
->IsSubMenu() )
105 result
= FindMenuItemByIdRecursive( item
->GetSubMenu(), id
);
112 wxMenuItem
* wxMenuBar::FindMenuItemById( int id
) const
114 wxMenuItem
* result
= 0;
115 wxNode
*node
= m_menus
.First();
116 while (node
&& result
== 0)
118 wxMenu
*menu
= (wxMenu
*)node
->Data();
119 result
= FindMenuItemByIdRecursive( menu
, id
);
125 bool wxMenuBar::IsChecked( int id
) const
127 wxMenuItem
* item
= FindMenuItemById( id
);
128 if (item
) return item
->IsChecked();
132 bool wxMenuBar::IsEnabled( int id
) const
134 wxMenuItem
* item
= FindMenuItemById( id
);
135 if (item
) return item
->IsEnabled();
139 //-----------------------------------------------------------------------------
141 //-----------------------------------------------------------------------------
143 void gtk_menu_clicked_callback( GtkWidget
*widget
, gpointer data
)
145 wxMenu
*menu
= (wxMenu
*)data
;
146 int id
= menu
->FindMenuIdByMenuItem(widget
);
148 wxASSERT( id
!= -1 ); // should find it!
150 if (!menu
->IsEnabled(id
))
153 wxCommandEvent
event( wxEVENT_TYPE_MENU_COMMAND
, id
);
154 event
.SetEventObject( menu
);
156 wxWindow
*win
= menu
->GetInvokingWindow();
157 if (win
) win
->GetEventHandler()->ProcessEvent( event
);
160 IMPLEMENT_DYNAMIC_CLASS(wxMenuItem
,wxObject
)
162 wxMenuItem::wxMenuItem()
165 m_isCheckMenu
= FALSE
;
172 void wxMenuItem::SetText(const wxString
& str
)
174 for ( const char *pc
= str
; *pc
!= '\0'; pc
++ ) {
182 void wxMenuItem::Check( bool check
)
184 wxCHECK_RET( IsCheckable(), "can't check uncheckable item!" )
187 gtk_check_menu_item_set_state( (GtkCheckMenuItem
*)m_menuItem
, (gint
)check
);
190 bool wxMenuItem::IsChecked() const
192 wxCHECK( IsCheckable(), FALSE
); // can't get state of uncheckable item!
194 bool bIsChecked
= ((GtkCheckMenuItem
*)m_menuItem
)->active
!= 0;
196 wxASSERT( bIsChecked
== m_isChecked
); // consistency check
201 IMPLEMENT_DYNAMIC_CLASS(wxMenu
,wxEvtHandler
)
203 wxMenu::wxMenu( const wxString
&title
)
206 m_items
.DeleteContents( TRUE
);
207 m_invokingWindow
= NULL
;
208 m_menu
= gtk_menu_new(); // Do not show!
211 void wxMenu::AppendSeparator()
213 wxMenuItem
*mitem
= new wxMenuItem();
214 mitem
->SetId(ID_SEPARATOR
);
216 GtkWidget
*menuItem
= gtk_menu_item_new();
217 gtk_menu_append( GTK_MENU(m_menu
), menuItem
);
218 gtk_widget_show( menuItem
);
219 mitem
->SetMenuItem(menuItem
);
220 m_items
.Append( mitem
);
223 void wxMenu::Append( int id
, const wxString
&item
, const wxString
&helpStr
, bool checkable
)
225 wxMenuItem
*mitem
= new wxMenuItem();
227 mitem
->SetText(item
);
228 mitem
->SetHelpString(helpStr
);
229 mitem
->SetCheckable(checkable
);
230 const char *text
= mitem
->GetText();
231 GtkWidget
*menuItem
= checkable
? gtk_check_menu_item_new_with_label(text
)
232 : gtk_menu_item_new_with_label(text
);
233 mitem
->SetMenuItem(menuItem
);
235 gtk_signal_connect( GTK_OBJECT(menuItem
), "activate",
236 GTK_SIGNAL_FUNC(gtk_menu_clicked_callback
),
239 gtk_menu_append( GTK_MENU(m_menu
), menuItem
);
240 gtk_widget_show( menuItem
);
241 m_items
.Append( mitem
);
244 void wxMenu::Append( int id
, const wxString
&text
, wxMenu
*subMenu
, const wxString
&helpStr
)
246 wxMenuItem
*mitem
= new wxMenuItem();
248 mitem
->SetText(text
);
250 GtkWidget
*menuItem
= gtk_menu_item_new_with_label(mitem
->GetText());
251 mitem
->SetHelpString(helpStr
);
252 mitem
->SetMenuItem(menuItem
);
253 mitem
->SetSubMenu(subMenu
);
255 gtk_menu_item_set_submenu( GTK_MENU_ITEM(menuItem
), subMenu
->m_menu
);
256 gtk_menu_append( GTK_MENU(m_menu
), menuItem
);
257 gtk_widget_show( menuItem
);
258 m_items
.Append( mitem
);
261 int wxMenu::FindItem( const wxString itemString
) const
263 wxString
s( itemString
);
267 pos
= s
.First( '&' );
268 if (pos
!= -1) s
.Remove( pos
, 1 );
271 wxNode
*node
= m_items
.First();
274 wxMenuItem
*item
= (wxMenuItem
*)node
->Data();
275 if (item
->GetText() == s
)
276 return item
->GetId();
283 void wxMenu::Enable( int id
, bool enable
)
285 wxMenuItem
*item
= FindItem(id
);
287 item
->Enable(enable
);
290 bool wxMenu::IsEnabled( int id
) const
292 wxMenuItem
*item
= FindItem(id
);
294 return item
->IsEnabled();
299 void wxMenu::Check( int id
, bool enable
)
301 wxMenuItem
*item
= FindItem(id
);
306 bool wxMenu::IsChecked( int id
) const
308 wxMenuItem
*item
= FindItem(id
);
310 return item
->IsChecked();
315 void wxMenu::SetLabel( int id
, const wxString
&label
)
317 wxMenuItem
*item
= FindItem(id
);
319 item
->SetText(label
);
322 int wxMenu::FindMenuIdByMenuItem( GtkWidget
*menuItem
) const
324 wxNode
*node
= m_items
.First();
327 wxMenuItem
*item
= (wxMenuItem
*)node
->Data();
328 if (item
->GetMenuItem() == menuItem
)
329 return item
->GetId();
336 wxMenuItem
*wxMenu::FindItem(int id
) const
338 wxNode
*node
= m_items
.First();
340 wxMenuItem
*item
= (wxMenuItem
*)node
->Data();
341 if ( item
->GetId() == id
)
346 wxLogDebug("wxMenu::FindItem: item %d not found.", id
);
351 void wxMenu::SetInvokingWindow( wxWindow
*win
)
353 m_invokingWindow
= win
;
356 wxWindow
*wxMenu::GetInvokingWindow()
358 return m_invokingWindow
;