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