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