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