]> git.saurik.com Git - wxWidgets.git/blob - src/gtk/menu.cpp
* added gtk_text_changed callback and implemented DiscardEdits(), so that
[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 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
95 //-----------------------------------------------------------------------------
96 // wxMenu
97 //-----------------------------------------------------------------------------
98
99 void gtk_menu_clicked_callback( GtkWidget *widget, gpointer data )
100 {
101 wxMenu *menu = (wxMenu*)data;
102 int id = menu->FindMenuIdByMenuItem(widget);
103
104 if (!menu->Enabled(id)) return;
105
106 wxCommandEvent event( wxEVENT_TYPE_MENU_COMMAND, id );
107 event.SetEventObject( menu );
108 event.SetInt(id );
109 wxWindow *win = menu->GetInvokingWindow();
110 if (win) win->ProcessEvent( event );
111 };
112
113 IMPLEMENT_DYNAMIC_CLASS(wxMenuItem,wxObject)
114
115 wxMenuItem::wxMenuItem(void)
116 {
117 m_id = 0;
118 m_text = "";
119 m_isCheckMenu = FALSE;
120 m_checked = FALSE;
121 m_isSubMenu = FALSE;
122 m_subMenu = NULL;
123 m_helpStr = "";
124 m_menuItem = NULL;
125 };
126
127 IMPLEMENT_DYNAMIC_CLASS(wxMenu,wxEvtHandler)
128
129 wxMenu::wxMenu( const wxString &title )
130 {
131 m_title = title;
132 m_items.DeleteContents( TRUE );
133 m_invokingWindow = NULL;
134 m_menu = gtk_menu_new(); // Do not show!
135 };
136
137 void wxMenu::AppendSeparator(void)
138 {
139 wxMenuItem *mitem = new wxMenuItem();
140 mitem->m_id = -1;
141 mitem->m_text = "";
142 mitem->m_helpStr = "";
143 mitem->m_isCheckMenu = FALSE;
144 mitem->m_isEnabled = TRUE;
145 mitem->m_menuItem = gtk_menu_item_new();
146 gtk_menu_append( GTK_MENU(m_menu), mitem->m_menuItem );
147 gtk_widget_show( mitem->m_menuItem );
148 m_items.Append( mitem );
149 };
150
151 void wxMenu::Append( const int id, const wxString &item, const wxString &helpStr, const bool checkable )
152 {
153 wxMenuItem *mitem = new wxMenuItem();
154 mitem->m_id = id;
155
156 mitem->m_text = item;
157 size_t pos;
158 do {
159 pos = mitem->m_text.First( '&' );
160 if (pos != wxString::npos) mitem->m_text.Remove( pos, 1 );
161 } while (pos != wxString::npos);
162
163 mitem->m_helpStr = helpStr;
164 mitem->m_isCheckMenu = checkable;
165 mitem->m_isEnabled = TRUE;
166 if (checkable)
167 mitem->m_menuItem = gtk_check_menu_item_new_with_label( WXSTRINGCAST(mitem->m_text) );
168 else
169 mitem->m_menuItem = gtk_menu_item_new_with_label( WXSTRINGCAST(mitem->m_text) );
170
171 gtk_signal_connect( GTK_OBJECT(mitem->m_menuItem), "activate",
172 GTK_SIGNAL_FUNC(gtk_menu_clicked_callback), (gpointer*)this );
173
174 gtk_menu_append( GTK_MENU(m_menu), mitem->m_menuItem );
175 gtk_widget_show( mitem->m_menuItem );
176 m_items.Append( mitem );
177 };
178
179 void wxMenu::Append( const int id, const wxString &item, wxMenu *subMenu, const wxString &helpStr )
180 {
181 wxMenuItem *mitem = new wxMenuItem();
182 mitem->m_id = id;
183 mitem->m_text = item;
184 mitem->m_isEnabled = TRUE;
185
186 size_t pos;
187 do {
188 pos = mitem->m_text.First( '&' );
189 if (pos != wxString::npos) mitem->m_text.Remove( pos, 1 );
190 } while (pos != wxString::npos);
191
192 mitem->m_helpStr = helpStr;
193 mitem->m_menuItem = gtk_menu_item_new_with_label( WXSTRINGCAST(mitem->m_text) );
194
195 mitem->m_subMenu = subMenu;
196 gtk_menu_item_set_submenu( GTK_MENU_ITEM(mitem->m_menuItem), subMenu->m_menu );
197 gtk_menu_append( GTK_MENU(m_menu), mitem->m_menuItem );
198 gtk_widget_show( mitem->m_menuItem );
199 m_items.Append( mitem );
200 };
201
202 int wxMenu::FindItem( const wxString itemString ) const
203 {
204 wxString s( itemString );
205
206 size_t pos;
207 do {
208 pos = s.First( '&' );
209 if (pos != wxString::npos) s.Remove( pos, 1 );
210 } while (pos != wxString::npos);
211
212 wxNode *node = m_items.First();
213 while (node)
214 {
215 wxMenuItem *item = (wxMenuItem*)node->Data();
216 if (item->m_text == s) return item->m_id;
217 node = node->Next();
218 };
219 return -1;
220 };
221
222 void wxMenu::Enable( const int id, const bool enable )
223 {
224 wxNode *node = m_items.First();
225 while (node)
226 {
227 wxMenuItem *item = (wxMenuItem*)node->Data();
228 if (item->m_id == id)
229 {
230 item->m_isEnabled = enable;
231 return;
232 };
233 node = node->Next();
234 };
235 };
236
237 bool wxMenu::Enabled( const int id ) const
238 {
239 wxNode *node = m_items.First();
240 while (node)
241 {
242 wxMenuItem *item = (wxMenuItem*)node->Data();
243 if (item->m_id == id) return item->m_isEnabled;
244 node = node->Next();
245 };
246 return FALSE;
247 };
248
249 void wxMenu::SetLabel( const int id, const wxString &label )
250 {
251 wxString s( label );
252 size_t pos;
253 do {
254 pos = s.First( '&' );
255 if (pos != wxString::npos) s.Remove( pos, 1 );
256 } while (pos != wxString::npos);
257
258 wxNode *node = m_items.First();
259 while (node)
260 {
261 wxMenuItem *item = (wxMenuItem*)node->Data();
262 item->m_text = s;
263 if (item->m_id == id)
264 {
265 gtk_label_set( GTK_LABEL( GTK_BIN(item->m_menuItem)->child ), WXSTRINGCAST(s) );
266 };
267 node = node->Next();
268 };
269 };
270
271 int wxMenu::FindMenuIdByMenuItem( GtkWidget *menuItem ) const
272 {
273 wxNode *node = m_items.First();
274 while (node)
275 {
276 wxMenuItem *item = (wxMenuItem*)node->Data();
277 if (item->m_menuItem == menuItem) return item->m_id;
278 node = node->Next();
279 };
280 return -1;
281 };
282
283 void wxMenu::SetInvokingWindow( wxWindow *win )
284 {
285 m_invokingWindow = win;
286 };
287
288 wxWindow *wxMenu::GetInvokingWindow(void)
289 {
290 return m_invokingWindow;
291 };
292
293