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"
18 //-----------------------------------------------------------------------------
20 //-----------------------------------------------------------------------------
22 IMPLEMENT_DYNAMIC_CLASS(wxMenuBar
,wxWindow
)
24 wxMenuBar::wxMenuBar(void)
26 m_needParent
= FALSE
; // hmmm
28 PreCreation( NULL
, -1, wxDefaultPosition
, wxDefaultSize
, 0, "menu" );
30 m_menus
.DeleteContents( TRUE
);
32 m_widget
= gtk_handle_box_new();
34 m_menubar
= gtk_menu_bar_new();
36 gtk_container_add( GTK_CONTAINER(m_widget
), m_menubar
);
38 gtk_widget_show( m_menubar
);
45 void wxMenuBar::Append( wxMenu
*menu
, const wxString
&title
)
47 m_menus
.Append( menu
);
48 menu
->m_title
= title
; // ??????
52 pos
= menu
->m_title
.First( '&' );
53 if (pos
!= wxString::npos
) menu
->m_title
.Remove( pos
, 1 );
54 } while (pos
!= wxString::npos
);
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
);
61 gtk_menu_bar_append( GTK_MENU_BAR(m_menubar
), root_menu
);
64 static int FindMenuItemRecursive( const wxMenu
*menu
, const wxString
&menuString
, const wxString
&itemString
)
66 if (menu
->m_title
== menuString
)
68 int res
= menu
->FindItem( itemString
);
69 if (res
!= -1) return res
;
71 wxNode
*node
= menu
->m_items
.First();
74 wxMenuItem
*item
= (wxMenuItem
*)node
->Data();
75 if (item
->m_subMenu
) return FindMenuItemRecursive( item
->m_subMenu
, menuString
, itemString
);
81 int wxMenuBar::FindMenuItem( const wxString
&menuString
, const wxString
&itemString
) const
83 wxNode
*node
= m_menus
.First();
86 wxMenu
*menu
= (wxMenu
*)node
->Data();
87 int res
= FindMenuItemRecursive( menu
, menuString
, itemString
);
88 if (res
!= -1) return res
;
94 // Find a wxMenuItem using its id. Recurses down into sub-menus
95 static wxMenuItem
* FindMenuItemByIdRecursive( const wxMenu
* menu
, int id
)
97 wxMenuItem
* result
= menu
->FindItemForId( id
);
99 wxNode
*node
= menu
->m_items
.First();
100 while (node
&& result
== 0)
102 wxMenuItem
*item
= (wxMenuItem
*)node
->Data();
103 if (item
->m_subMenu
) result
= FindMenuItemByIdRecursive( item
->m_subMenu
, 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 bool wxMenuBar::IsChecked( int id
) const
124 wxMenuItem
* item
= FindMenuItemById( id
);
125 if (item
) return item
->IsChecked();
129 bool wxMenuBar::IsEnabled( int id
) const
131 wxMenuItem
* item
= FindMenuItemById( id
);
132 if (item
) return item
->IsEnabled();
136 //-----------------------------------------------------------------------------
138 //-----------------------------------------------------------------------------
140 void gtk_menu_clicked_callback( GtkWidget
*widget
, gpointer data
)
142 wxMenu
*menu
= (wxMenu
*)data
;
143 int id
= menu
->FindMenuIdByMenuItem(widget
);
145 if (!menu
->Enabled(id
)) return;
147 wxCommandEvent
event( wxEVENT_TYPE_MENU_COMMAND
, id
);
148 event
.SetEventObject( menu
);
150 wxWindow
*win
= menu
->GetInvokingWindow();
151 if (win
) win
->ProcessEvent( event
);
154 IMPLEMENT_DYNAMIC_CLASS(wxMenuItem
,wxObject
)
156 wxMenuItem::wxMenuItem(void)
160 m_isCheckMenu
= FALSE
;
168 void wxMenuItem::Check( bool check
)
173 gtk_check_menu_item_set_state( (GtkCheckMenuItem
*)m_menuItem
, (gint
)check
);
177 bool wxMenuItem::IsChecked() const
181 return ((GtkCheckMenuItem
*)m_menuItem
)->active
!= 0;
186 void wxMenuItem::Enable( bool enable
)
188 m_isEnabled
= enable
;
191 IMPLEMENT_DYNAMIC_CLASS(wxMenu
,wxEvtHandler
)
193 wxMenu::wxMenu( const wxString
&title
)
196 m_items
.DeleteContents( TRUE
);
197 m_invokingWindow
= NULL
;
198 m_menu
= gtk_menu_new(); // Do not show!
201 void wxMenu::AppendSeparator(void)
203 wxMenuItem
*mitem
= new wxMenuItem();
204 mitem
->m_id
= ID_SEPARATOR
;
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
);
215 void wxMenu::Append( int id
, const wxString
&item
, const wxString
&helpStr
, bool checkable
)
217 wxMenuItem
*mitem
= new wxMenuItem();
220 mitem
->m_text
= item
;
223 pos
= mitem
->m_text
.First( '&' );
224 if (pos
!= wxString::npos
) mitem
->m_text
.Remove( pos
, 1 );
225 } while (pos
!= wxString::npos
);
227 mitem
->m_helpStr
= helpStr
;
228 mitem
->m_isCheckMenu
= checkable
;
229 mitem
->m_isEnabled
= TRUE
;
231 mitem
->m_menuItem
= gtk_check_menu_item_new_with_label( WXSTRINGCAST(mitem
->m_text
) );
233 mitem
->m_menuItem
= gtk_menu_item_new_with_label( WXSTRINGCAST(mitem
->m_text
) );
235 gtk_signal_connect( GTK_OBJECT(mitem
->m_menuItem
), "activate",
236 GTK_SIGNAL_FUNC(gtk_menu_clicked_callback
), (gpointer
*)this );
238 gtk_menu_append( GTK_MENU(m_menu
), mitem
->m_menuItem
);
239 gtk_widget_show( mitem
->m_menuItem
);
240 m_items
.Append( mitem
);
243 void wxMenu::Append( int id
, const wxString
&item
, wxMenu
*subMenu
, const wxString
&helpStr
)
245 wxMenuItem
*mitem
= new wxMenuItem();
247 mitem
->m_text
= item
;
248 mitem
->m_isEnabled
= TRUE
;
252 pos
= mitem
->m_text
.First( '&' );
253 if (pos
!= wxString::npos
) mitem
->m_text
.Remove( pos
, 1 );
254 } while (pos
!= wxString::npos
);
256 mitem
->m_helpStr
= helpStr
;
257 mitem
->m_menuItem
= gtk_menu_item_new_with_label( WXSTRINGCAST(mitem
->m_text
) );
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
);
266 int wxMenu::FindItem( const wxString itemString
) const
268 wxString
s( itemString
);
272 pos
= s
.First( '&' );
273 if (pos
!= wxString::npos
) s
.Remove( pos
, 1 );
274 } while (pos
!= wxString::npos
);
276 wxNode
*node
= m_items
.First();
279 wxMenuItem
*item
= (wxMenuItem
*)node
->Data();
280 if (item
->m_text
== s
) return item
->m_id
;
286 wxMenuItem
* wxMenu::FindItemForId( int id
) const
288 wxNode
*node
= m_items
.First();
291 wxMenuItem
*item
= (wxMenuItem
*)node
->Data();
292 if (item
->m_id
== id
) return item
;
298 void wxMenu::Check( int id
, bool Flag
)
300 wxMenuItem
* item
= FindItemForId( id
);
301 if (item
) item
->Check(Flag
);
304 void wxMenu::Enable( int id
, bool enable
)
306 wxNode
*node
= m_items
.First();
309 wxMenuItem
*item
= (wxMenuItem
*)node
->Data();
310 if (item
->m_id
== id
)
312 item
->m_isEnabled
= enable
;
319 bool wxMenu::Enabled( int id
) const
321 wxNode
*node
= m_items
.First();
324 wxMenuItem
*item
= (wxMenuItem
*)node
->Data();
325 if (item
->m_id
== id
) return item
->m_isEnabled
;
331 void wxMenu::SetLabel( int id
, const wxString
&label
)
336 pos
= s
.First( '&' );
337 if (pos
!= wxString::npos
) s
.Remove( pos
, 1 );
338 } while (pos
!= wxString::npos
);
340 wxNode
*node
= m_items
.First();
343 wxMenuItem
*item
= (wxMenuItem
*)node
->Data();
345 if (item
->m_id
== id
)
347 gtk_label_set( GTK_LABEL( GTK_BIN(item
->m_menuItem
)->child
), WXSTRINGCAST(s
) );
353 int wxMenu::FindMenuIdByMenuItem( GtkWidget
*menuItem
) const
355 wxNode
*node
= m_items
.First();
358 wxMenuItem
*item
= (wxMenuItem
*)node
->Data();
359 if (item
->m_menuItem
== menuItem
) return item
->m_id
;
365 void wxMenu::SetInvokingWindow( wxWindow
*win
)
367 m_invokingWindow
= win
;
370 wxWindow
*wxMenu::GetInvokingWindow(void)
372 return m_invokingWindow
;