]> git.saurik.com Git - wxWidgets.git/blame - src/motif/menu.cpp
Added missing includes
[wxWidgets.git] / src / motif / menu.cpp
CommitLineData
4bb6408c 1/////////////////////////////////////////////////////////////////////////////
355b4d3d 2// Name: src/motif/menu.cpp
4bb6408c
JS
3// Purpose: wxMenu, wxMenuBar, wxMenuItem
4// Author: Julian Smart
5// Modified by:
6// Created: 17/09/98
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart
65571936 9// Licence: wxWindows licence
4bb6408c
JS
10/////////////////////////////////////////////////////////////////////////////
11
4bb6408c 12// ============================================================================
9874b4ee 13// declarations
4bb6408c
JS
14// ============================================================================
15
9874b4ee
VZ
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
1248b41f
MB
20// For compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
22
4bb6408c 23#include "wx/menu.h"
e4db172a
WS
24
25#ifndef WX_PRECOMP
26 #include "wx/log.h"
670f9935 27 #include "wx/app.h"
de6185e2 28 #include "wx/utils.h"
76b49cf4 29 #include "wx/frame.h"
9eddec69 30 #include "wx/settings.h"
25466131 31 #include "wx/menuitem.h"
e4db172a
WS
32#endif
33
338dd992
JJ
34#ifdef __VMS__
35#pragma message disable nosimpint
4dff3400
JJ
36#define XtDisplay XTDISPLAY
37#define XtWindow XTWINDOW
338dd992 38#endif
4bb6408c
JS
39#include <Xm/Label.h>
40#include <Xm/LabelG.h>
41#include <Xm/CascadeBG.h>
42#include <Xm/CascadeB.h>
43#include <Xm/SeparatoG.h>
44#include <Xm/PushBG.h>
45#include <Xm/ToggleB.h>
46#include <Xm/ToggleBG.h>
47#include <Xm/RowColumn.h>
338dd992
JJ
48#ifdef __VMS__
49#pragma message enable nosimpint
50#endif
4bb6408c 51
50414e24
JS
52#include "wx/motif/private.h"
53
4bb6408c 54// other standard headers
4bb6408c
JS
55#include <string.h>
56
4bb6408c
JS
57IMPLEMENT_DYNAMIC_CLASS(wxMenu, wxEvtHandler)
58IMPLEMENT_DYNAMIC_CLASS(wxMenuBar, wxEvtHandler)
4bb6408c
JS
59
60// ============================================================================
61// implementation
62// ============================================================================
63
9874b4ee 64// ----------------------------------------------------------------------------
4bb6408c 65// Menus
9874b4ee 66// ----------------------------------------------------------------------------
4bb6408c
JS
67
68// Construct a menu with optional title (then use append)
c71830c3 69void wxMenu::Init()
4bb6408c 70{
c71830c3 71 // Motif-specific members
4bb6408c
JS
72 m_numColumns = 1;
73 m_menuWidget = (WXWidget) NULL;
74 m_popupShell = (WXWidget) NULL;
75 m_buttonWidget = (WXWidget) NULL;
76 m_menuId = 0;
50414e24 77 m_topLevelMenu = (wxMenu*) NULL;
96be256b 78 m_ownedByMenuBar = false;
bf6c2b35 79
12cca26a 80 if ( !m_title.empty() )
4bb6408c 81 {
15b845f2 82 Append(-3, m_title) ;
4bb6408c
JS
83 AppendSeparator() ;
84 }
4bb6408c
JS
85}
86
87// The wxWindow destructor will take care of deleting the submenus.
88wxMenu::~wxMenu()
89{
50414e24
JS
90 if (m_menuWidget)
91 {
2d120f83 92 if (m_menuParent)
96be256b 93 DestroyMenu(true);
2d120f83 94 else
96be256b 95 DestroyMenu(false);
50414e24 96 }
bf6c2b35 97
50414e24
JS
98 // Not sure if this is right
99 if (m_menuParent && m_menuBar)
100 {
2d120f83
JS
101 m_menuParent = NULL;
102 // m_menuBar = NULL;
50414e24 103 }
4bb6408c
JS
104}
105
106void wxMenu::Break()
107{
c71830c3 108 m_numColumns++;
4bb6408c
JS
109}
110
111// function appends a new item or submenu to the menu
9add9367 112wxMenuItem* wxMenu::DoAppend(wxMenuItem *pItem)
4bb6408c 113{
51c9a5db 114 return DoInsert(GetMenuItemCount(), pItem);
4bb6408c
JS
115}
116
c71830c3 117wxMenuItem *wxMenu::DoRemove(wxMenuItem *item)
4bb6408c 118{
96be256b 119 item->DestroyItem(true);
bf6c2b35 120
c71830c3 121 return wxMenuBase::DoRemove(item);
4bb6408c
JS
122}
123
9add9367 124wxMenuItem* wxMenu::DoInsert(size_t pos, wxMenuItem *item)
4bb6408c 125{
51c9a5db
MB
126 if (m_menuWidget)
127 {
128 // this is a dynamic Append
129#ifndef XmNpositionIndex
130 wxCHECK_MSG( pos == GetMenuItemCount(), -1, wxT("insert not implemented"));
131#endif
132 item->CreateItem(m_menuWidget, GetMenuBar(), m_topLevelMenu, pos);
133 }
4bb6408c 134
51c9a5db
MB
135 if ( item->IsSubMenu() )
136 {
137 item->GetSubMenu()->m_topLevelMenu = m_topLevelMenu;
138 }
bf6c2b35 139
355b4d3d 140 return pos == GetMenuItemCount() ? wxMenuBase::DoAppend(item) :
51c9a5db 141 wxMenuBase::DoInsert(pos, item);
4bb6408c
JS
142}
143
144void wxMenu::SetTitle(const wxString& label)
145{
c71830c3 146 m_title = label;
bf6c2b35 147
ac32ba44 148 wxMenuItemList::compatibility_iterator node = GetMenuItems().GetFirst();
c71830c3 149 if ( !node )
2d120f83 150 return;
bf6c2b35 151
c71830c3 152 wxMenuItem *item = node->GetData ();
50414e24 153 Widget widget = (Widget) item->GetButtonWidget();
c71830c3 154 if ( !widget )
2d120f83 155 return;
bf6c2b35 156
c71830c3
VZ
157 wxXmString title_str(label);
158 XtVaSetValues(widget,
159 XmNlabelString, title_str(),
160 NULL);
4bb6408c
JS
161}
162
c71830c3 163bool wxMenu::ProcessCommand(wxCommandEvent & event)
4bb6408c 164{
09294e12
VZ
165 // Try the menu's event handler first
166 wxEvtHandler * const handler = GetEventHandler();
167 bool processed = handler ? handler->SafelyProcessEvent(event) : false;
bf6c2b35 168
4bb6408c
JS
169 // Try the window the menu was popped up from (and up
170 // through the hierarchy)
171 if ( !processed && GetInvokingWindow())
09294e12 172 processed = GetInvokingWindow()->HandleWindowEvent(event);
631f1bfe 173
c71830c3 174 return processed;
4bb6408c
JS
175}
176
9874b4ee 177// ----------------------------------------------------------------------------
4bb6408c 178// Menu Bar
9874b4ee 179// ----------------------------------------------------------------------------
4bb6408c 180
9874b4ee 181void wxMenuBar::Init()
cba2db0c
JS
182{
183 m_eventHandler = this;
cba2db0c
JS
184 m_menuBarFrame = NULL;
185 m_mainWidget = (WXWidget) NULL;
cba2db0c
JS
186}
187
294ea16d 188wxMenuBar::wxMenuBar(size_t n, wxMenu *menus[], const wxArrayString& titles, long WXUNUSED(style))
584ad2a3 189{
12cca26a 190 wxASSERT( n == titles.GetCount() );
584ad2a3
MB
191
192 Init();
193
194 m_titles = titles;
12cca26a 195 for ( size_t i = 0; i < n; i++ )
584ad2a3
MB
196 m_menus.Append(menus[i]);
197}
198
294ea16d 199wxMenuBar::wxMenuBar(size_t n, wxMenu *menus[], const wxString titles[], long WXUNUSED(style))
4bb6408c 200{
9874b4ee 201 Init();
4bb6408c 202
d2103c8c 203 for ( size_t i = 0; i < n; i++ )
4bb6408c 204 {
9874b4ee
VZ
205 m_menus.Append(menus[i]);
206 m_titles.Add(titles[i]);
4bb6408c 207 }
4bb6408c
JS
208}
209
9874b4ee 210wxMenuBar::~wxMenuBar()
4bb6408c 211{
9874b4ee 212 // nothing to do: wxMenuBarBase will delete the menus
4bb6408c
JS
213}
214
9874b4ee 215void wxMenuBar::EnableTop(size_t WXUNUSED(pos), bool WXUNUSED(flag))
4bb6408c 216{
6adaedf0 217 // wxFAIL_MSG("TODO");
23a8562d 218// wxLogWarning("wxMenuBar::EnableTop not yet implemented.");
4bb6408c
JS
219}
220
52af3158 221void wxMenuBar::SetMenuLabel(size_t pos, const wxString& label)
4bb6408c 222{
9874b4ee
VZ
223 wxMenu *menu = GetMenu(pos);
224 if ( !menu )
4bb6408c 225 return;
bf6c2b35 226
9874b4ee
VZ
227 Widget w = (Widget)menu->GetButtonWidget();
228 if (w)
229 {
230 wxXmString label_str(label);
bf6c2b35 231
9874b4ee
VZ
232 XtVaSetValues(w,
233 XmNlabelString, label_str(),
234 NULL);
235 }
927f01da 236 m_titles[pos] = label;
4bb6408c
JS
237}
238
52af3158 239wxString wxMenuBar::GetMenuLabel(size_t pos) const
4bb6408c 240{
52af3158
JS
241 wxCHECK_MSG( pos < GetMenuCount(), wxEmptyString,
242 wxT("invalid menu index in wxMenuBar::GetMenuLabel") );
243 return m_titles[pos];
4bb6408c
JS
244}
245
9874b4ee 246bool wxMenuBar::Append(wxMenu * menu, const wxString& title)
4bb6408c 247{
51c9a5db
MB
248 return Insert(GetMenuCount(), menu, title);
249}
250
251bool wxMenuBar::Insert(size_t pos, wxMenu *menu, const wxString& title)
252{
253 wxCHECK_MSG( pos <= GetMenuCount(), false, wxT("invalid position") );
96be256b
MB
254 wxCHECK_MSG( menu, false, wxT("invalid menu") );
255 wxCHECK_MSG( !menu->GetParent() && !menu->GetButtonWidget(), false,
9874b4ee 256 wxT("menu already appended") );
bf6c2b35 257
9874b4ee 258 if ( m_menuBarFrame )
50414e24 259 {
51c9a5db
MB
260 WXWidget w = menu->CreateMenu(this, GetMainWidget(), menu,
261 pos, title, true);
96be256b 262 wxCHECK_MSG( w, false, wxT("failed to create menu") );
9874b4ee 263 menu->SetButtonWidget(w);
50414e24 264 }
bf6c2b35 265
51c9a5db 266 m_titles.Insert(title, pos);
bf6c2b35 267
51c9a5db 268 return wxMenuBarBase::Insert(pos, menu, title);
4bb6408c
JS
269}
270
9874b4ee 271wxMenu *wxMenuBar::Replace(size_t pos, wxMenu *menu, const wxString& title)
4bb6408c 272{
9874b4ee 273 if ( !wxMenuBarBase::Replace(pos, menu, title) )
81b29996 274 return NULL;
bf6c2b35 275
9874b4ee 276 wxFAIL_MSG(wxT("TODO"));
bf6c2b35 277
9874b4ee 278 return NULL;
4bb6408c
JS
279}
280
9874b4ee 281wxMenu *wxMenuBar::Remove(size_t pos)
4bb6408c 282{
9874b4ee
VZ
283 wxMenu *menu = wxMenuBarBase::Remove(pos);
284 if ( !menu )
285 return NULL;
bf6c2b35 286
9874b4ee 287 if ( m_menuBarFrame )
96be256b 288 menu->DestroyMenu(true);
bf6c2b35 289
9874b4ee 290 menu->SetMenuBar(NULL);
bf6c2b35 291
ba8c1601 292 m_titles.RemoveAt(pos);
bf6c2b35 293
9874b4ee 294 return menu;
4bb6408c
JS
295}
296
297// Find the menu menuString, item itemString, and return the item id.
298// Returns -1 if none found.
db927071 299int wxMenuBar::FindMenuItem(const wxString& menuString, const wxString& itemString) const
4bb6408c 300{
db927071 301 const wxString stripped = wxStripMenuCodes(menuString);
9874b4ee
VZ
302
303 size_t menuCount = GetMenuCount();
304 for (size_t i = 0; i < menuCount; i++)
4bb6408c 305 {
db927071 306 if ( wxStripMenuCodes(m_titles[i]) == stripped )
ac32ba44 307 return m_menus.Item(i)->GetData()->FindItem (itemString);
4bb6408c 308 }
db927071 309 return wxNOT_FOUND;
4bb6408c
JS
310}
311
9874b4ee 312wxMenuItem *wxMenuBar::FindItem(int id, wxMenu ** itemMenu) const
4bb6408c
JS
313{
314 if (itemMenu)
315 *itemMenu = NULL;
bf6c2b35 316
9874b4ee
VZ
317 size_t menuCount = GetMenuCount();
318 for (size_t i = 0; i < menuCount; i++)
355b4d3d
WS
319 {
320 wxMenuItem *item = m_menus.Item(i)->GetData()->FindItem(id, itemMenu);
321 if (item) return item;
322 }
323
324 return NULL;
4bb6408c
JS
325}
326
621793f4
JS
327// Create menubar
328bool wxMenuBar::CreateMenuBar(wxFrame* parent)
329{
105fbe1f
MB
330 m_parent = parent; // bleach... override it!
331 PreCreation();
332 m_parent = NULL;
333
2d120f83 334 if (m_mainWidget)
621793f4 335 {
1c4f8f8d 336 XtVaSetValues((Widget) parent->GetMainWidget(), XmNmenuBar, (Widget) m_mainWidget, NULL);
2d120f83
JS
337 /*
338 if (!XtIsManaged((Widget) m_mainWidget))
339 XtManageChild((Widget) m_mainWidget);
340 */
341 XtMapWidget((Widget) m_mainWidget);
96be256b 342 return true;
621793f4 343 }
bf6c2b35 344
f1db433a
VZ
345 Widget menuBarW = XmCreateMenuBar ((Widget) parent->GetMainWidget(),
346 wxMOTIF_STR("MenuBar"), NULL, 0);
2d120f83 347 m_mainWidget = (WXWidget) menuBarW;
bf6c2b35 348
9874b4ee
VZ
349 size_t menuCount = GetMenuCount();
350 for (size_t i = 0; i < menuCount; i++)
2d120f83
JS
351 {
352 wxMenu *menu = GetMenu(i);
353 wxString title(m_titles[i]);
51c9a5db 354 menu->SetButtonWidget(menu->CreateMenu (this, menuBarW, menu, i, title, true));
bf6c2b35 355
31528cd3 356 if (strcmp (wxStripMenuCodes(title), "Help") == 0)
2d120f83 357 XtVaSetValues ((Widget) menuBarW, XmNmenuHelpWidget, (Widget) menu->GetButtonWidget(), NULL);
ee31c392
VZ
358
359 // tear off menu support
360#if (XmVersion >= 1002)
361 if ( menu->IsTearOff() )
362 {
363 XtVaSetValues(GetWidget(menu),
364 XmNtearOffModel, XmTEAR_OFF_ENABLED,
365 NULL);
6adaedf0
JS
366 Widget tearOff = XmGetTearOffControl(GetWidget(menu));
367 wxDoChangeForegroundColour((Widget) tearOff, m_foregroundColour);
96be256b 368 wxDoChangeBackgroundColour((Widget) tearOff, m_backgroundColour, true);
ee31c392
VZ
369#endif
370 }
2d120f83 371 }
bf6c2b35 372
105fbe1f 373 PostCreation();
bf6c2b35 374
1c4f8f8d 375 XtVaSetValues((Widget) parent->GetMainWidget(), XmNmenuBar, (Widget) m_mainWidget, NULL);
2d120f83
JS
376 XtRealizeWidget ((Widget) menuBarW);
377 XtManageChild ((Widget) menuBarW);
378 SetMenuBarFrame(parent);
bf6c2b35 379
96be256b 380 return true;
621793f4
JS
381}
382
383// Destroy menubar, but keep data structures intact so we can recreate it.
384bool wxMenuBar::DestroyMenuBar()
385{
2d120f83 386 if (!m_mainWidget)
621793f4 387 {
2d120f83 388 SetMenuBarFrame((wxFrame*) NULL);
96be256b 389 return false;
621793f4 390 }
bf6c2b35 391
2d120f83
JS
392 XtUnmanageChild ((Widget) m_mainWidget);
393 XtUnrealizeWidget ((Widget) m_mainWidget);
bf6c2b35 394
9874b4ee
VZ
395 size_t menuCount = GetMenuCount();
396 for (size_t i = 0; i < menuCount; i++)
2d120f83
JS
397 {
398 wxMenu *menu = GetMenu(i);
96be256b 399 menu->DestroyMenu(true);
bf6c2b35 400
2d120f83
JS
401 }
402 XtDestroyWidget((Widget) m_mainWidget);
403 m_mainWidget = (WXWidget) 0;
bf6c2b35 404
2d120f83 405 SetMenuBarFrame((wxFrame*) NULL);
bf6c2b35 406
96be256b 407 return true;
621793f4
JS
408}
409
7e1bcfa8
MB
410// Since PopupMenu under Motif stills grab right mouse button events
411// after it was closed, we need to delete the associated widgets to
412// allow next PopUpMenu to appear...
413void wxMenu::DestroyWidgetAndDetach()
50414e24 414{
7e1bcfa8 415 if (GetMainWidget())
c71830c3 416 {
7e1bcfa8 417 wxMenu *menuParent = GetParent();
c71830c3 418 if ( menuParent )
2d120f83 419 {
ac32ba44 420 wxMenuItemList::compatibility_iterator node = menuParent->GetMenuItems().GetFirst();
c71830c3
VZ
421 while ( node )
422 {
7e1bcfa8 423 if ( node->GetData()->GetSubMenu() == this )
c71830c3 424 {
ac32ba44
MB
425 delete node->GetData();
426 menuParent->GetMenuItems().Erase(node);
c71830c3
VZ
427
428 break;
429 }
430
431 node = node->GetNext();
432 }
2d120f83 433 }
c71830c3 434
96be256b 435 DestroyMenu(true);
7fe7d506 436 }
c71830c3
VZ
437
438 // Mark as no longer popped up
7e1bcfa8 439 m_menuId = -1;
50414e24
JS
440}
441
442/*
2d120f83
JS
443* Create a popup or pulldown menu.
444* Submenus of a popup will be pulldown.
445*
446*/
50414e24 447
355b4d3d
WS
448WXWidget wxMenu::CreateMenu (wxMenuBar * menuBar,
449 WXWidget parent,
450 wxMenu * topMenu,
451 size_t WXUNUSED(index),
452 const wxString& title,
453 bool pullDown)
50414e24 454{
2d120f83
JS
455 Widget menu = (Widget) 0;
456 Widget buttonWidget = (Widget) 0;
105fbe1f 457 Display* dpy = XtDisplay((Widget)parent);
2d120f83
JS
458 Arg args[5];
459 XtSetArg (args[0], XmNnumColumns, m_numColumns);
4464ec9e 460 XtSetArg (args[1], XmNpacking, (m_numColumns > 1) ? XmPACK_COLUMN : XmPACK_TIGHT);
bf6c2b35 461
105fbe1f
MB
462 if ( !m_font.Ok() )
463 {
464 if ( menuBar )
465 m_font = menuBar->GetFont();
466 else if ( GetInvokingWindow() )
467 m_font = GetInvokingWindow()->GetFont();
468 }
469
470 XtSetArg (args[2], (String)wxFont::GetFontTag(), m_font.GetFontTypeC(dpy) );
471
2d120f83 472 if (!pullDown)
50414e24 473 {
105fbe1f 474 menu = XmCreatePopupMenu ((Widget) parent, wxMOTIF_STR("popup"), args, 3);
7e1bcfa8 475#if 0
2d120f83 476 XtAddCallback(menu,
bf6c2b35 477 XmNunmapCallback,
2d120f83
JS
478 (XtCallbackProc)wxMenuPopdownCallback,
479 (XtPointer)this);
7e1bcfa8 480#endif
50414e24 481 }
2d120f83 482 else
50414e24 483 {
2d120f83 484 char mnem = wxFindMnemonic (title);
105fbe1f 485 menu = XmCreatePulldownMenu ((Widget) parent, wxMOTIF_STR("pulldown"), args, 3);
bf6c2b35 486
31528cd3
VZ
487 wxString title2(wxStripMenuCodes(title));
488 wxXmString label_str(title2);
489 buttonWidget = XtVaCreateManagedWidget(title2,
47d67540 490#if wxUSE_GADGETS
2d120f83 491 xmCascadeButtonGadgetClass, (Widget) parent,
50414e24 492#else
2d120f83 493 xmCascadeButtonWidgetClass, (Widget) parent,
50414e24 494#endif
193fe989 495 XmNlabelString, label_str(),
2d120f83 496 XmNsubMenuId, menu,
105fbe1f
MB
497 (String)wxFont::GetFontTag(), m_font.GetFontTypeC(dpy),
498 XmNpositionIndex, index,
2d120f83 499 NULL);
bf6c2b35 500
2d120f83
JS
501 if (mnem != 0)
502 XtVaSetValues (buttonWidget, XmNmnemonic, mnem, NULL);
50414e24 503 }
bf6c2b35 504
2d120f83 505 m_menuWidget = (WXWidget) menu;
bf6c2b35 506
2d120f83 507 m_topLevelMenu = topMenu;
bf6c2b35 508
51c9a5db 509 size_t i = 0;
ac32ba44 510 for ( wxMenuItemList::compatibility_iterator node = GetMenuItems().GetFirst();
c71830c3 511 node;
51c9a5db 512 node = node->GetNext(), ++i )
50414e24 513 {
c71830c3
VZ
514 wxMenuItem *item = node->GetData();
515
51c9a5db 516 item->CreateItem(menu, menuBar, topMenu, i);
50414e24 517 }
bf6c2b35 518
105fbe1f 519 ChangeFont();
bf6c2b35 520
2d120f83 521 return buttonWidget;
50414e24
JS
522}
523
524// Destroys the Motif implementation of the menu,
77ffb593 525// but maintains the wxWidgets data structures so we can
bf6c2b35 526// do a CreateMenu again.
50414e24
JS
527void wxMenu::DestroyMenu (bool full)
528{
ac32ba44 529 for ( wxMenuItemList::compatibility_iterator node = GetMenuItems().GetFirst();
c71830c3
VZ
530 node;
531 node = node->GetNext() )
50414e24 532 {
c71830c3 533 wxMenuItem *item = node->GetData();
2d120f83 534 item->SetMenuBar((wxMenuBar*) NULL);
bf6c2b35 535
2d120f83 536 item->DestroyItem(full);
c71830c3 537 }
bf6c2b35 538
2d120f83 539 if (m_buttonWidget)
50414e24 540 {
2d120f83
JS
541 if (full)
542 {
543 XtVaSetValues((Widget) m_buttonWidget, XmNsubMenuId, NULL, NULL);
544 XtDestroyWidget ((Widget) m_buttonWidget);
545 m_buttonWidget = (WXWidget) 0;
546 }
50414e24 547 }
2d120f83 548 if (m_menuWidget && full)
50414e24 549 {
2d120f83
JS
550 XtDestroyWidget((Widget) m_menuWidget);
551 m_menuWidget = (WXWidget) NULL;
50414e24
JS
552 }
553}
554
555WXWidget wxMenu::FindMenuItem (int id, wxMenuItem ** it) const
556{
2d120f83 557 if (id == m_menuId)
50414e24 558 {
2d120f83
JS
559 if (it)
560 *it = (wxMenuItem*) NULL;
561 return m_buttonWidget;
50414e24 562 }
bf6c2b35 563
ac32ba44 564 for ( wxMenuItemList::compatibility_iterator node = GetMenuItems().GetFirst();
c71830c3
VZ
565 node;
566 node = node->GetNext() )
50414e24 567 {
c71830c3 568 wxMenuItem *item = node->GetData ();
2d120f83
JS
569 if (item->GetId() == id)
570 {
571 if (it)
572 *it = item;
573 return item->GetButtonWidget();
574 }
bf6c2b35 575
2d120f83
JS
576 if (item->GetSubMenu())
577 {
578 WXWidget w = item->GetSubMenu()->FindMenuItem (id, it);
579 if (w)
580 {
581 return w;
582 }
583 }
c71830c3 584 }
bf6c2b35 585
2d120f83
JS
586 if (it)
587 *it = (wxMenuItem*) NULL;
588 return (WXWidget) NULL;
50414e24 589}
94b49b93
JS
590
591void wxMenu::SetBackgroundColour(const wxColour& col)
592{
593 m_backgroundColour = col;
105fbe1f
MB
594 if (!col.Ok())
595 return;
94b49b93 596 if (m_menuWidget)
2d120f83 597 wxDoChangeBackgroundColour(m_menuWidget, (wxColour&) col);
94b49b93 598 if (m_buttonWidget)
96be256b 599 wxDoChangeBackgroundColour(m_buttonWidget, (wxColour&) col, true);
bf6c2b35 600
ac32ba44 601 for ( wxMenuItemList::compatibility_iterator node = GetMenuItems().GetFirst();
c71830c3
VZ
602 node;
603 node = node->GetNext() )
94b49b93 604 {
c71830c3 605 wxMenuItem* item = node->GetData();
94b49b93
JS
606 if (item->GetButtonWidget())
607 {
2d120f83 608 // This crashes because it uses gadgets
96be256b 609 // wxDoChangeBackgroundColour(item->GetButtonWidget(), (wxColour&) col, true);
94b49b93
JS
610 }
611 if (item->GetSubMenu())
2d120f83 612 item->GetSubMenu()->SetBackgroundColour((wxColour&) col);
94b49b93
JS
613 }
614}
615
616void wxMenu::SetForegroundColour(const wxColour& col)
617{
618 m_foregroundColour = col;
105fbe1f
MB
619 if (!col.Ok())
620 return;
94b49b93 621 if (m_menuWidget)
2d120f83 622 wxDoChangeForegroundColour(m_menuWidget, (wxColour&) col);
94b49b93 623 if (m_buttonWidget)
2d120f83 624 wxDoChangeForegroundColour(m_buttonWidget, (wxColour&) col);
bf6c2b35 625
ac32ba44 626 for ( wxMenuItemList::compatibility_iterator node = GetMenuItems().GetFirst();
c71830c3
VZ
627 node;
628 node = node->GetNext() )
94b49b93 629 {
c71830c3 630 wxMenuItem* item = node->GetData();
94b49b93
JS
631 if (item->GetButtonWidget())
632 {
2d120f83
JS
633 // This crashes because it uses gadgets
634 // wxDoChangeForegroundColour(item->GetButtonWidget(), (wxColour&) col);
94b49b93
JS
635 }
636 if (item->GetSubMenu())
2d120f83 637 item->GetSubMenu()->SetForegroundColour((wxColour&) col);
94b49b93
JS
638 }
639}
640
641void wxMenu::ChangeFont(bool keepOriginalSize)
642{
101b4778
MB
643 // Lesstif 0.87 hangs here, but 0.93 does not; MBN: sometimes it does
644#if !wxCHECK_LESSTIF() // || wxCHECK_LESSTIF_VERSION( 0, 93 )
94b49b93
JS
645 if (!m_font.Ok() || !m_menuWidget)
646 return;
bf6c2b35 647
73608949 648 Display* dpy = XtDisplay((Widget) m_menuWidget);
bf6c2b35 649
94b49b93 650 XtVaSetValues ((Widget) m_menuWidget,
73608949 651 wxFont::GetFontTag(), m_font.GetFontTypeC(dpy),
da494b40 652 NULL);
94b49b93
JS
653 if (m_buttonWidget)
654 {
2d120f83 655 XtVaSetValues ((Widget) m_buttonWidget,
73608949 656 wxFont::GetFontTag(), m_font.GetFontTypeC(dpy),
da494b40 657 NULL);
94b49b93 658 }
c71830c3 659
ac32ba44 660 for ( wxMenuItemList::compatibility_iterator node = GetMenuItems().GetFirst();
c71830c3
VZ
661 node;
662 node = node->GetNext() )
94b49b93 663 {
c71830c3 664 wxMenuItem* item = node->GetData();
94b49b93
JS
665 if (m_menuWidget && item->GetButtonWidget() && m_font.Ok())
666 {
2d120f83 667 XtVaSetValues ((Widget) item->GetButtonWidget(),
73608949 668 wxFont::GetFontTag(), m_font.GetFontTypeC(dpy),
da494b40 669 NULL);
94b49b93
JS
670 }
671 if (item->GetSubMenu())
2d120f83 672 item->GetSubMenu()->ChangeFont(keepOriginalSize);
94b49b93 673 }
355b4d3d
WS
674#else
675 wxUnusedVar(keepOriginalSize);
94b49b93
JS
676#endif
677}
678
679void wxMenu::SetFont(const wxFont& font)
680{
681 m_font = font;
682 ChangeFont();
683}
684
9874b4ee 685bool wxMenuBar::SetBackgroundColour(const wxColour& col)
94b49b93 686{
105fbe1f
MB
687 if (!wxWindowBase::SetBackgroundColour(col))
688 return false;
689 if (!col.Ok())
690 return false;
94b49b93 691 if (m_mainWidget)
2d120f83 692 wxDoChangeBackgroundColour(m_mainWidget, (wxColour&) col);
9874b4ee
VZ
693
694 size_t menuCount = GetMenuCount();
695 for (size_t i = 0; i < menuCount; i++)
ac32ba44 696 m_menus.Item(i)->GetData()->SetBackgroundColour((wxColour&) col);
9874b4ee 697
96be256b 698 return true;
94b49b93
JS
699}
700
9874b4ee 701bool wxMenuBar::SetForegroundColour(const wxColour& col)
94b49b93 702{
105fbe1f
MB
703 if (!wxWindowBase::SetForegroundColour(col))
704 return false;
705 if (!col.Ok())
706 return false;
94b49b93 707 if (m_mainWidget)
2d120f83 708 wxDoChangeForegroundColour(m_mainWidget, (wxColour&) col);
bf6c2b35 709
9874b4ee
VZ
710 size_t menuCount = GetMenuCount();
711 for (size_t i = 0; i < menuCount; i++)
ac32ba44 712 m_menus.Item(i)->GetData()->SetForegroundColour((wxColour&) col);
9874b4ee 713
96be256b 714 return true;
94b49b93
JS
715}
716
af111fc3 717void wxMenuBar::ChangeFont(bool WXUNUSED(keepOriginalSize))
94b49b93 718{
2d120f83 719 // Nothing to do for menubar, fonts are kept in wxMenus
94b49b93
JS
720}
721
9874b4ee 722bool wxMenuBar::SetFont(const wxFont& font)
94b49b93
JS
723{
724 m_font = font;
725 ChangeFont();
bf6c2b35 726
9874b4ee
VZ
727 size_t menuCount = GetMenuCount();
728 for (size_t i = 0; i < menuCount; i++)
ac32ba44 729 m_menus.Item(i)->GetData()->SetFont(font);
9874b4ee 730
96be256b 731 return true;
94b49b93 732}