]> git.saurik.com Git - wxWidgets.git/blob - src/mac/menu.cpp
wxPython doc updates
[wxWidgets.git] / src / mac / menu.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: menu.cpp
3 // Purpose: wxMenu, wxMenuBar, wxMenuItem
4 // Author: AUTHOR
5 // Modified by:
6 // Created: ??/??/98
7 // RCS-ID: $Id$
8 // Copyright: (c) AUTHOR
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12
13 // ============================================================================
14 // headers & declarations
15 // ============================================================================
16
17 // wxWindows headers
18 // -----------------
19
20 #ifdef __GNUG__
21 #pragma implementation "menu.h"
22 #pragma implementation "menuitem.h"
23 #endif
24
25 #include "wx/menu.h"
26 #include "wx/menuitem.h"
27 #include "wx/log.h"
28 #include "wx/utils.h"
29
30 // other standard headers
31 // ----------------------
32 #include <string.h>
33
34 #if !USE_SHARED_LIBRARY
35 IMPLEMENT_DYNAMIC_CLASS(wxMenu, wxEvtHandler)
36 IMPLEMENT_DYNAMIC_CLASS(wxMenuBar, wxEvtHandler)
37 #endif
38
39 // ============================================================================
40 // implementation
41 // ============================================================================
42
43 // Menus
44
45 // Construct a menu with optional title (then use append)
46 wxMenu::wxMenu(const wxString& title, const wxFunction func)
47 {
48 m_title = title;
49 m_parent = NULL;
50 m_eventHandler = this;
51 m_noItems = 0;
52 m_menuBar = NULL;
53 m_clientData = (void*) NULL;
54 if (m_title != "")
55 {
56 Append(-2, m_title) ;
57 AppendSeparator() ;
58 }
59
60 Callback(func);
61
62 // TODO create menu
63 }
64
65 // The wxWindow destructor will take care of deleting the submenus.
66 wxMenu::~wxMenu()
67 {
68 // TODO destroy menu and children
69
70 wxNode *node = m_menuItems.First();
71 while (node)
72 {
73 wxMenuItem *item = (wxMenuItem *)node->Data();
74
75 // Delete child menus.
76 // Beware: they must not be appended to children list!!!
77 // (because order of delete is significant)
78 if (item->GetSubMenu())
79 item->DeleteSubMenu();
80
81 wxNode *next = node->Next();
82 delete item;
83 delete node;
84 node = next;
85 }
86 }
87
88 void wxMenu::Break()
89 {
90 // TODO
91 }
92
93 // function appends a new item or submenu to the menu
94 void wxMenu::Append(wxMenuItem *pItem)
95 {
96 // TODO
97
98 wxCHECK_RET( pItem != NULL, "can't append NULL item to the menu" );
99
100 m_menuItems.Append(pItem);
101
102 m_noItems++;
103 }
104
105 void wxMenu::AppendSeparator()
106 {
107 // TODO
108 Append(new wxMenuItem(this, ID_SEPARATOR));
109 }
110
111 // Pullright item
112 void wxMenu::Append(int Id, const wxString& label, wxMenu *SubMenu,
113 const wxString& helpString)
114 {
115 Append(new wxMenuItem(this, Id, label, helpString, FALSE, SubMenu));
116 }
117
118 // Ordinary menu item
119 void wxMenu::Append(int Id, const wxString& label,
120 const wxString& helpString, bool checkable)
121 {
122 // 'checkable' parameter is useless for Windows.
123 Append(new wxMenuItem(this, Id, label, helpString, checkable));
124 }
125
126 void wxMenu::Delete(int id)
127 {
128 wxNode *node;
129 wxMenuItem *item;
130 int pos;
131
132 for (pos = 0, node = m_menuItems.First(); node; node = node->Next(), pos++) {
133 item = (wxMenuItem *)node->Data();
134 if (item->GetId() == id)
135 break;
136 }
137
138 if (!node)
139 return;
140
141 m_menuItems.DeleteNode(node);
142 delete item;
143
144 // TODO
145 }
146
147 void wxMenu::Enable(int Id, bool Flag)
148 {
149 wxMenuItem *item = FindItemForId(Id);
150 wxCHECK_RET( item != NULL, "can't enable non-existing menu item" );
151
152 item->Enable(Flag);
153 }
154
155 bool wxMenu::Enabled(int Id) const
156 {
157 wxMenuItem *item = FindItemForId(Id);
158 wxCHECK( item != NULL, FALSE );
159
160 return item->IsEnabled();
161 }
162
163 void wxMenu::Check(int Id, bool Flag)
164 {
165 wxMenuItem *item = FindItemForId(Id);
166 wxCHECK_RET( item != NULL, "can't get status of non-existing menu item" );
167
168 item->Check(Flag);
169 }
170
171 bool wxMenu::Checked(int Id) const
172 {
173 wxMenuItem *item = FindItemForId(Id);
174 wxCHECK( item != NULL, FALSE );
175
176 return item->IsChecked();
177 }
178
179 void wxMenu::SetTitle(const wxString& label)
180 {
181 m_title = label ;
182 // TODO
183 }
184
185 const wxString wxMenu::GetTitle() const
186 {
187 return m_title;
188 }
189
190 void wxMenu::SetLabel(int id, const wxString& label)
191 {
192 wxMenuItem *item = FindItemForId(id) ;
193 if (item==NULL)
194 return;
195
196 if (item->GetSubMenu()==NULL)
197 {
198 // TODO
199 }
200 else
201 {
202 // TODO
203 }
204 item->SetName(label);
205 }
206
207 wxString wxMenu::GetLabel(int Id) const
208 {
209 // TODO
210 return wxString("") ;
211 }
212
213 // Finds the item id matching the given string, -1 if not found.
214 int wxMenu::FindItem (const wxString& itemString) const
215 {
216 char buf1[200];
217 char buf2[200];
218 wxStripMenuCodes ((char *)(const char *)itemString, buf1);
219
220 for (wxNode * node = m_menuItems.First (); node; node = node->Next ())
221 {
222 wxMenuItem *item = (wxMenuItem *) node->Data ();
223 if (item->GetSubMenu())
224 {
225 int ans = item->GetSubMenu()->FindItem(itemString);
226 if (ans > -1)
227 return ans;
228 }
229 if ( !item->IsSeparator() )
230 {
231 wxStripMenuCodes((char *)item->GetName().c_str(), buf2);
232 if (strcmp(buf1, buf2) == 0)
233 return item->GetId();
234 }
235 }
236
237 return -1;
238 }
239
240 wxMenuItem *wxMenu::FindItemForId(int itemId, wxMenu ** itemMenu) const
241 {
242 if (itemMenu)
243 *itemMenu = NULL;
244 for (wxNode * node = m_menuItems.First (); node; node = node->Next ())
245 {
246 wxMenuItem *item = (wxMenuItem *) node->Data ();
247
248 if (item->GetId() == itemId)
249 {
250 if (itemMenu)
251 *itemMenu = (wxMenu *) this;
252 return item;
253 }
254
255 if (item->GetSubMenu())
256 {
257 wxMenuItem *ans = item->GetSubMenu()->FindItemForId (itemId, itemMenu);
258 if (ans)
259 return ans;
260 }
261 }
262
263 if (itemMenu)
264 *itemMenu = NULL;
265 return NULL;
266 }
267
268 void wxMenu::SetHelpString(int itemId, const wxString& helpString)
269 {
270 wxMenuItem *item = FindItemForId (itemId);
271 if (item)
272 item->SetHelp(helpString);
273 }
274
275 wxString wxMenu::GetHelpString (int itemId) const
276 {
277 wxMenuItem *item = FindItemForId (itemId);
278 wxString str("");
279 return (item == NULL) ? str : item->GetHelp();
280 }
281
282 void wxMenu::ProcessCommand(wxCommandEvent & event)
283 {
284 bool processed = FALSE;
285
286 // Try a callback
287 if (m_callback)
288 {
289 (void) (*(m_callback)) (*this, event);
290 processed = TRUE;
291 }
292
293 // Try the menu's event handler
294 if ( !processed && GetEventHandler())
295 {
296 processed = GetEventHandler()->ProcessEvent(event);
297 }
298 /* TODO
299 // Try the window the menu was popped up from (and up
300 // through the hierarchy)
301 if ( !processed && GetInvokingWindow())
302 processed = GetInvokingWindow()->ProcessEvent(event);
303 */
304 }
305
306 bool wxWindow::PopupMenu(wxMenu *menu, int x, int y)
307 {
308 // TODO
309 return FALSE;
310 }
311
312 // Menu Bar
313 wxMenuBar::wxMenuBar()
314 {
315 m_eventHandler = this;
316 m_menuCount = 0;
317 m_menus = NULL;
318 m_titles = NULL;
319 m_menuBarFrame = NULL;
320
321 // TODO
322 }
323
324 wxMenuBar::wxMenuBar(int n, wxMenu *menus[], const wxString titles[])
325 {
326 m_eventHandler = this;
327 m_menuCount = n;
328 m_menus = menus;
329 m_titles = new wxString[n];
330 int i;
331 for ( i = 0; i < n; i++ )
332 m_titles[i] = titles[i];
333 m_menuBarFrame = NULL;
334
335 // TODO
336 }
337
338 wxMenuBar::~wxMenuBar()
339 {
340 int i;
341 for (i = 0; i < m_menuCount; i++)
342 {
343 delete m_menus[i];
344 }
345 delete[] m_menus;
346 delete[] m_titles;
347
348 // TODO
349 }
350
351 // Must only be used AFTER menu has been attached to frame,
352 // otherwise use individual menus to enable/disable items
353 void wxMenuBar::Enable(int id, bool flag)
354 {
355 wxMenu *itemMenu = NULL;
356 wxMenuItem *item = FindItemForId(id, &itemMenu) ;
357 if (!item)
358 return;
359
360 // TODO
361 }
362
363 void wxMenuBar::EnableTop(int pos, bool flag)
364 {
365 // TODO
366 }
367
368 // Must only be used AFTER menu has been attached to frame,
369 // otherwise use individual menus
370 void wxMenuBar::Check(int id, bool flag)
371 {
372 wxMenu *itemMenu = NULL;
373 wxMenuItem *item = FindItemForId(id, &itemMenu) ;
374 if (!item)
375 return;
376
377 if (!item->IsCheckable())
378 return ;
379
380 // TODO
381 }
382
383 bool wxMenuBar::Checked(int id) const
384 {
385 wxMenu *itemMenu = NULL;
386 wxMenuItem *item = FindItemForId(id, &itemMenu) ;
387 if (!item)
388 return FALSE;
389
390 // TODO
391 return FALSE;
392 }
393
394 bool wxMenuBar::Enabled(int id) const
395 {
396 wxMenu *itemMenu = NULL;
397 wxMenuItem *item = FindItemForId(id, &itemMenu) ;
398 if (!item)
399 return FALSE;
400
401 // TODO
402 return FALSE ;
403 }
404
405
406 void wxMenuBar::SetLabel(int id, const wxString& label)
407 {
408 wxMenu *itemMenu = NULL;
409 wxMenuItem *item = FindItemForId(id, &itemMenu) ;
410
411 if (!item)
412 return;
413
414 // TODO
415 }
416
417 wxString wxMenuBar::GetLabel(int id) const
418 {
419 wxMenu *itemMenu = NULL;
420 wxMenuItem *item = FindItemForId(id, &itemMenu) ;
421
422 if (!item)
423 return wxString("");
424
425 // TODO
426 return wxString("") ;
427 }
428
429 void wxMenuBar::SetLabelTop(int pos, const wxString& label)
430 {
431 // TODO
432 }
433
434 wxString wxMenuBar::GetLabelTop(int pos) const
435 {
436 // TODO
437 return wxString("");
438 }
439
440 bool wxMenuBar::OnDelete(wxMenu *a_menu, int pos)
441 {
442 // TODO
443 return FALSE;
444 }
445
446 bool wxMenuBar::OnAppend(wxMenu *a_menu, const char *title)
447 {
448 // TODO
449 return FALSE;
450 }
451
452 void wxMenuBar::Append (wxMenu * menu, const wxString& title)
453 {
454 if (!OnAppend(menu, title))
455 return;
456
457 m_menuCount ++;
458 wxMenu **new_menus = new wxMenu *[m_menuCount];
459 wxString *new_titles = new wxString[m_menuCount];
460 int i;
461
462 for (i = 0; i < m_menuCount - 1; i++)
463 {
464 new_menus[i] = m_menus[i];
465 m_menus[i] = NULL;
466 new_titles[i] = m_titles[i];
467 m_titles[i] = "";
468 }
469 if (m_menus)
470 {
471 delete[]m_menus;
472 delete[]m_titles;
473 }
474 m_menus = new_menus;
475 m_titles = new_titles;
476
477 m_menus[m_menuCount - 1] = (wxMenu *)menu;
478 m_titles[m_menuCount - 1] = title;
479
480 // TODO
481 }
482
483 void wxMenuBar::Delete(wxMenu * menu, int i)
484 {
485 int j;
486 int ii = (int) i;
487
488 if (menu != 0)
489 {
490 for (ii = 0; ii < m_menuCount; ii++)
491 {
492 if (m_menus[ii] == menu)
493 break;
494 }
495 if (ii >= m_menuCount)
496 return;
497 } else
498 {
499 if (ii < 0 || ii >= m_menuCount)
500 return;
501 menu = m_menus[ii];
502 }
503
504 if (!OnDelete(menu, ii))
505 return;
506
507 menu->SetParent(NULL);
508
509 -- m_menuCount;
510 for (j = ii; j < m_menuCount; j++)
511 {
512 m_menus[j] = m_menus[j + 1];
513 m_titles[j] = m_titles[j + 1];
514 }
515 }
516
517 // Find the menu menuString, item itemString, and return the item id.
518 // Returns -1 if none found.
519 int wxMenuBar::FindMenuItem (const wxString& menuString, const wxString& itemString) const
520 {
521 char buf1[200];
522 char buf2[200];
523 wxStripMenuCodes ((char *)(const char *)menuString, buf1);
524 int i;
525 for (i = 0; i < m_menuCount; i++)
526 {
527 wxStripMenuCodes ((char *)(const char *)m_titles[i], buf2);
528 if (strcmp (buf1, buf2) == 0)
529 return m_menus[i]->FindItem (itemString);
530 }
531 return -1;
532 }
533
534 wxMenuItem *wxMenuBar::FindItemForId (int Id, wxMenu ** itemMenu) const
535 {
536 if (itemMenu)
537 *itemMenu = NULL;
538
539 wxMenuItem *item = NULL;
540 int i;
541 for (i = 0; i < m_menuCount; i++)
542 if ((item = m_menus[i]->FindItemForId (Id, itemMenu)))
543 return item;
544 return NULL;
545 }
546
547 void wxMenuBar::SetHelpString (int Id, const wxString& helpString)
548 {
549 int i;
550 for (i = 0; i < m_menuCount; i++)
551 {
552 if (m_menus[i]->FindItemForId (Id))
553 {
554 m_menus[i]->SetHelpString (Id, helpString);
555 return;
556 }
557 }
558 }
559
560 wxString wxMenuBar::GetHelpString (int Id) const
561 {
562 int i;
563 for (i = 0; i < m_menuCount; i++)
564 {
565 if (m_menus[i]->FindItemForId (Id))
566 return wxString(m_menus[i]->GetHelpString (Id));
567 }
568 return wxString("");
569 }
570
571