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