1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxMenu, wxMenuBar, wxMenuItem
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 // ============================================================================
14 // headers & declarations
15 // ============================================================================
21 #pragma implementation "menu.h"
22 #pragma implementation "menuitem.h"
26 #include "wx/menuitem.h"
31 #include "wx/settings.h"
34 #include <Xm/LabelG.h>
35 #include <Xm/CascadeBG.h>
36 #include <Xm/CascadeB.h>
37 #include <Xm/SeparatoG.h>
38 #include <Xm/PushBG.h>
39 #include <Xm/ToggleB.h>
40 #include <Xm/ToggleBG.h>
41 #include <Xm/RowColumn.h>
43 #include "wx/motif/private.h"
45 // other standard headers
46 // ----------------------
49 #if !USE_SHARED_LIBRARY
50 IMPLEMENT_DYNAMIC_CLASS(wxMenu
, wxEvtHandler
)
51 IMPLEMENT_DYNAMIC_CLASS(wxMenuBar
, wxEvtHandler
)
54 // ============================================================================
56 // ============================================================================
60 // Construct a menu with optional title (then use append)
61 wxMenu::wxMenu(const wxString
& title
, const wxFunction func
)
64 m_parent
= (wxEvtHandler
*) NULL
;
65 m_eventHandler
= this;
68 m_pInvokingWindow
= NULL
;
70 //// Motif-specific members
72 m_menuWidget
= (WXWidget
) NULL
;
73 m_popupShell
= (WXWidget
) NULL
;
74 m_buttonWidget
= (WXWidget
) NULL
;
76 m_topLevelMenu
= (wxMenu
*) NULL
;
77 m_ownedByMenuBar
= FALSE
;
78 m_menuParent
= (wxMenu
*) NULL
;
79 m_clientData
= (void*) NULL
;
83 Append(ID_SEPARATOR
, m_title
) ;
86 m_backgroundColour
= wxSystemSettings::GetSystemColour(wxSYS_COLOUR_MENU
);
87 m_foregroundColour
= wxSystemSettings::GetSystemColour(wxSYS_COLOUR_MENUTEXT
);
88 m_font
= wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT
);
93 // The wxWindow destructor will take care of deleting the submenus.
104 // Not sure if this is right
105 if (m_menuParent
&& m_menuBar
)
111 wxNode
*node
= m_menuItems
.First();
114 wxMenuItem
*item
= (wxMenuItem
*)node
->Data();
117 if (item->GetSubMenu())
118 item->DeleteSubMenu();
121 wxNode
*next
= node
->Next();
133 // function appends a new item or submenu to the menu
134 void wxMenu::Append(wxMenuItem
*pItem
)
136 wxCHECK_RET( pItem
!= NULL
, "can't append NULL item to the menu" );
138 m_menuItems
.Append(pItem
);
141 pItem
->CreateItem (m_menuWidget
, m_menuBar
, m_topLevelMenu
); // this is a dynamic Append
146 void wxMenu::AppendSeparator()
148 Append(new wxMenuItem(this, ID_SEPARATOR
));
152 // N.B.: difference between old and new code.
153 // Old code stores subMenu in 'children' for later deletion,
154 // as well as in m_menuItems, whereas we only store it in
155 // m_menuItems here. What implications does this have?
157 void wxMenu::Append(int id
, const wxString
& label
, wxMenu
*subMenu
,
158 const wxString
& helpString
)
160 Append(new wxMenuItem(this, id
, label
, helpString
, FALSE
, subMenu
));
162 subMenu
->m_topLevelMenu
= m_topLevelMenu
;
165 // Ordinary menu item
166 void wxMenu::Append(int id
, const wxString
& label
,
167 const wxString
& helpString
, bool checkable
)
169 // 'checkable' parameter is useless for Windows.
170 Append(new wxMenuItem(this, id
, label
, helpString
, checkable
));
173 void wxMenu::Delete(int id
)
179 for (pos
= 0, node
= m_menuItems
.First(); node
; node
= node
->Next(), pos
++)
181 item
= (wxMenuItem
*)node
->Data();
182 if (item
->GetId() == id
)
189 item
->DestroyItem(TRUE
);
191 // See also old code - don't know if this is needed (seems redundant).
193 if (item->GetSubMenu()) {
194 item->subMenu->top_level_menu = item->GetSubMenu();
195 item->subMenu->window_parent = NULL;
196 children->DeleteObject(item->GetSubMenu());
200 m_menuItems
.DeleteNode(node
);
204 void wxMenu::Enable(int id
, bool flag
)
206 wxMenuItem
*item
= FindItemForId(id
);
207 wxCHECK_RET( item
!= NULL
, "can't enable non-existing menu item" );
212 bool wxMenu::Enabled(int Id
) const
214 wxMenuItem
*item
= FindItemForId(Id
);
215 wxCHECK( item
!= NULL
, FALSE
);
217 return item
->IsEnabled();
220 void wxMenu::Check(int Id
, bool Flag
)
222 wxMenuItem
*item
= FindItemForId(Id
);
223 wxCHECK_RET( item
!= NULL
, "can't get status of non-existing menu item" );
228 bool wxMenu::Checked(int id
) const
230 wxMenuItem
*item
= FindItemForId(id
);
231 wxCHECK( item
!= NULL
, FALSE
);
233 return item
->IsChecked();
236 void wxMenu::SetTitle(const wxString
& label
)
240 wxNode
*node
= m_menuItems
.First ();
244 wxMenuItem
*item
= (wxMenuItem
*) node
->Data ();
245 Widget widget
= (Widget
) item
->GetButtonWidget();
249 XmString title_str
= XmStringCreateSimple ((char*) (const char*) label
);
250 XtVaSetValues (widget
,
251 XmNlabelString
, title_str
,
253 // TODO: should we delete title_str now?
256 const wxString
wxMenu::GetTitle() const
261 void wxMenu::SetLabel(int id
, const wxString
& label
)
263 wxMenuItem
*item
= FindItemForId(id
);
264 if (item
== (wxMenuItem
*) NULL
)
267 item
->SetLabel(label
);
270 wxString
wxMenu::GetLabel(int id
) const
272 wxMenuItem
*it
= NULL
;
273 WXWidget w
= FindMenuItem (id
, &it
);
278 XtVaGetValues ((Widget
) w
,
279 XmNlabelString
, &text
,
282 if (XmStringGetLtoR (text
, XmSTRING_DEFAULT_CHARSET
, &s
))
291 return wxEmptyString
;
295 return wxEmptyString
;
298 // Finds the item id matching the given string, -1 if not found.
299 int wxMenu::FindItem (const wxString
& itemString
) const
303 wxStripMenuCodes ((char *)(const char *)itemString
, buf1
);
305 for (wxNode
* node
= m_menuItems
.First (); node
; node
= node
->Next ())
307 wxMenuItem
*item
= (wxMenuItem
*) node
->Data ();
308 if (item
->GetSubMenu())
310 int ans
= item
->GetSubMenu()->FindItem(itemString
);
314 if ( !item
->IsSeparator() )
316 wxStripMenuCodes((char *)item
->GetName().c_str(), buf2
);
317 if (strcmp(buf1
, buf2
) == 0)
318 return item
->GetId();
325 wxMenuItem
*wxMenu::FindItemForId(int itemId
, wxMenu
** itemMenu
) const
329 for (wxNode
* node
= m_menuItems
.First (); node
; node
= node
->Next ())
331 wxMenuItem
*item
= (wxMenuItem
*) node
->Data ();
333 if (item
->GetId() == itemId
)
336 *itemMenu
= (wxMenu
*) this;
340 if (item
->GetSubMenu())
342 wxMenuItem
*ans
= item
->GetSubMenu()->FindItemForId (itemId
, itemMenu
);
353 void wxMenu::SetHelpString(int itemId
, const wxString
& helpString
)
355 wxMenuItem
*item
= FindItemForId (itemId
);
357 item
->SetHelp(helpString
);
360 wxString
wxMenu::GetHelpString (int itemId
) const
362 wxMenuItem
*item
= FindItemForId (itemId
);
364 return (item
== NULL
) ? str
: item
->GetHelp();
367 void wxMenu::ProcessCommand(wxCommandEvent
& event
)
369 bool processed
= FALSE
;
374 (void) (*(m_callback
)) (*this, event
);
378 // Try the menu's event handler
379 if ( !processed
&& GetEventHandler())
381 processed
= GetEventHandler()->ProcessEvent(event
);
383 // Try the window the menu was popped up from (and up
384 // through the hierarchy)
385 if ( !processed
&& GetInvokingWindow())
386 processed
= GetInvokingWindow()->ProcessEvent(event
);
389 // Update a menu and all submenus recursively.
390 // source is the object that has the update event handlers
391 // defined for it. If NULL, the menu or associated window
393 void wxMenu::UpdateUI(wxEvtHandler
* source
)
395 if (!source
&& GetInvokingWindow())
396 source
= GetInvokingWindow()->GetEventHandler();
398 source
= GetEventHandler();
402 wxNode
* node
= GetItems().First();
405 wxMenuItem
* item
= (wxMenuItem
*) node
->Data();
406 if ( !item
->IsSeparator() )
408 wxWindowID id
= item
->GetId();
409 wxUpdateUIEvent
event(id
);
410 event
.SetEventObject( source
);
412 if (source
->ProcessEvent(event
))
414 if (event
.GetSetText())
415 SetLabel(id
, event
.GetText());
416 if (event
.GetSetChecked())
417 Check(id
, event
.GetChecked());
418 if (event
.GetSetEnabled())
419 Enable(id
, event
.GetEnabled());
422 if (item
->GetSubMenu())
423 item
->GetSubMenu()->UpdateUI(source
);
429 bool wxWindow::PopupMenu(wxMenu
*menu
, int x
, int y
)
431 Widget widget
= (Widget
) GetMainWidget();
433 /* The menuId field seems to be usused, so we'll use it to
434 indicate whether a menu is popped up or not:
435 0: Not currently created as a popup
436 -1: Created as a popup, but not active
440 if (menu
->GetParent() && (menu
->GetId() != -1))
443 if (menu
->GetMainWidget()) {
444 menu
->DestroyMenu(TRUE
);
447 wxWindow
*parent
= this;
449 menu
->SetId(1); /* Mark as popped-up */
450 menu
->CreateMenu(NULL
, widget
, menu
);
451 menu
->SetInvokingWindow(this);
455 // menu->SetParent(parent);
456 // parent->children->Append(menu); // Store menu for later deletion
458 Widget menuWidget
= (Widget
) menu
->GetMainWidget();
466 if (this->IsKindOf(CLASSINFO(wxCanvas)))
468 wxCanvas *canvas = (wxCanvas *) this;
469 deviceX = canvas->GetDC ()->LogicalToDeviceX (x);
470 deviceY = canvas->GetDC ()->LogicalToDeviceY (y);
474 Display
*display
= XtDisplay (widget
);
475 Window rootWindow
= RootWindowOfScreen (XtScreen((Widget
)widget
));
476 Window thisWindow
= XtWindow (widget
);
478 XTranslateCoordinates (display
, thisWindow
, rootWindow
, (int) deviceX
, (int) deviceY
,
479 &rootX
, &rootY
, &childWindow
);
481 XButtonPressedEvent event
;
482 event
.type
= ButtonPress
;
488 event
.x_root
= rootX
;
489 event
.y_root
= rootY
;
491 XmMenuPosition (menuWidget
, &event
);
492 XtManageChild (menuWidget
);
498 wxMenuBar::wxMenuBar()
500 m_eventHandler
= this;
504 m_menuBarFrame
= NULL
;
505 m_mainWidget
= (WXWidget
) NULL
;
506 m_backgroundColour
= wxSystemSettings::GetSystemColour(wxSYS_COLOUR_MENU
);
507 m_foregroundColour
= wxSystemSettings::GetSystemColour(wxSYS_COLOUR_MENUTEXT
);
508 m_font
= wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT
);
511 wxMenuBar::wxMenuBar(long WXUNUSED(style
))
513 m_eventHandler
= this;
517 m_menuBarFrame
= NULL
;
518 m_mainWidget
= (WXWidget
) NULL
;
519 m_backgroundColour
= wxSystemSettings::GetSystemColour(wxSYS_COLOUR_MENU
);
520 m_foregroundColour
= wxSystemSettings::GetSystemColour(wxSYS_COLOUR_MENUTEXT
);
521 m_font
= wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT
);
524 wxMenuBar::wxMenuBar(int n
, wxMenu
*menus
[], const wxString titles
[])
526 m_eventHandler
= this;
529 m_titles
= new wxString
[n
];
531 for ( i
= 0; i
< n
; i
++ )
532 m_titles
[i
] = titles
[i
];
533 m_menuBarFrame
= NULL
;
534 m_backgroundColour
= wxSystemSettings::GetSystemColour(wxSYS_COLOUR_MENU
);
535 m_foregroundColour
= wxSystemSettings::GetSystemColour(wxSYS_COLOUR_MENUTEXT
);
536 m_font
= wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT
);
539 wxMenuBar::~wxMenuBar()
542 for (i
= 0; i
< m_menuCount
; i
++)
550 // Must only be used AFTER menu has been attached to frame,
551 // otherwise use individual menus to enable/disable items
552 void wxMenuBar::Enable(int id
, bool flag
)
554 wxMenu
*itemMenu
= NULL
;
555 wxMenuItem
*item
= FindItemForId(id
, &itemMenu
) ;
561 void wxMenuBar::EnableTop(int pos
, bool flag
)
566 // Must only be used AFTER menu has been attached to frame,
567 // otherwise use individual menus
568 void wxMenuBar::Check(int id
, bool flag
)
570 wxMenu
*itemMenu
= NULL
;
571 wxMenuItem
*item
= FindItemForId(id
, &itemMenu
) ;
575 if (!item
->IsCheckable())
581 bool wxMenuBar::Checked(int id
) const
583 wxMenu
*itemMenu
= NULL
;
584 wxMenuItem
*item
= FindItemForId(id
, &itemMenu
) ;
588 return item
->IsChecked();
591 bool wxMenuBar::Enabled(int id
) const
593 wxMenu
*itemMenu
= NULL
;
594 wxMenuItem
*item
= FindItemForId(id
, &itemMenu
) ;
598 return item
->IsEnabled();
601 void wxMenuBar::SetLabel(int id
, const wxString
& label
)
603 wxMenu
*itemMenu
= NULL
;
604 wxMenuItem
*item
= FindItemForId(id
, &itemMenu
) ;
609 item
->SetLabel(label
);
612 wxString
wxMenuBar::GetLabel(int id
) const
614 wxMenu
*itemMenu
= NULL
;
615 wxMenuItem
*item
= FindItemForId(id
, &itemMenu
) ;
620 return item
->GetLabel();
623 void wxMenuBar::SetLabelTop(int pos
, const wxString
& label
)
625 wxASSERT( (pos
< m_menuCount
) );
627 Widget w
= (Widget
) m_menus
[pos
]->GetButtonWidget();
630 XmString label_str
= XmStringCreateSimple ((char*) (const char*) label
);
632 XmNlabelString
, label_str
,
634 XmStringFree (label_str
);
638 wxString
wxMenuBar::GetLabelTop(int pos
) const
640 wxASSERT( (pos
< m_menuCount
) );
642 Widget w
= (Widget
) m_menus
[pos
]->GetButtonWidget();
648 XmNlabelString
, &text
,
651 if (XmStringGetLtoR (text
, XmSTRING_DEFAULT_CHARSET
, &s
))
659 return wxEmptyString
;
663 return wxEmptyString
;
667 bool wxMenuBar::OnDelete(wxMenu
*menu
, int pos
)
669 // Only applies to dynamic deletion (when set in frame)
673 menu
->DestroyMenu(TRUE
);
677 bool wxMenuBar::OnAppend(wxMenu
*menu
, const char *title
)
679 // Only applies to dynamic append (when set in frame)
683 // Probably should be an assert here
684 if (menu
->GetParent())
687 // Has already been appended
688 if (menu
->GetButtonWidget())
691 WXWidget w
= menu
->CreateMenu(this, GetMainWidget(), menu
, title
, TRUE
);
692 menu
->SetButtonWidget(w
);
697 void wxMenuBar::Append (wxMenu
* menu
, const wxString
& title
)
699 if (!OnAppend(menu
, title
))
703 wxMenu
**new_menus
= new wxMenu
*[m_menuCount
];
704 wxString
*new_titles
= new wxString
[m_menuCount
];
707 for (i
= 0; i
< m_menuCount
- 1; i
++)
709 new_menus
[i
] = m_menus
[i
];
711 new_titles
[i
] = m_titles
[i
];
720 m_titles
= new_titles
;
722 m_menus
[m_menuCount
- 1] = (wxMenu
*)menu
;
723 m_titles
[m_menuCount
- 1] = title
;
725 menu
->SetMenuBar(this);
726 menu
->SetParent(this);
729 void wxMenuBar::Delete(wxMenu
* menu
, int i
)
736 for (ii
= 0; ii
< m_menuCount
; ii
++)
738 if (m_menus
[ii
] == menu
)
741 if (ii
>= m_menuCount
)
745 if (ii
< 0 || ii
>= m_menuCount
)
750 if (!OnDelete(menu
, ii
))
753 menu
->SetParent((wxEvtHandler
*) NULL
);
756 for (j
= ii
; j
< m_menuCount
; j
++)
758 m_menus
[j
] = m_menus
[j
+ 1];
759 m_titles
[j
] = m_titles
[j
+ 1];
763 // Find the menu menuString, item itemString, and return the item id.
764 // Returns -1 if none found.
765 int wxMenuBar::FindMenuItem (const wxString
& menuString
, const wxString
& itemString
) const
769 wxStripMenuCodes ((char *)(const char *)menuString
, buf1
);
771 for (i
= 0; i
< m_menuCount
; i
++)
773 wxStripMenuCodes ((char *)(const char *)m_titles
[i
], buf2
);
774 if (strcmp (buf1
, buf2
) == 0)
775 return m_menus
[i
]->FindItem (itemString
);
780 wxMenuItem
*wxMenuBar::FindItemForId (int id
, wxMenu
** itemMenu
) const
785 wxMenuItem
*item
= NULL
;
787 for (i
= 0; i
< m_menuCount
; i
++)
788 if ((item
= m_menus
[i
]->FindItemForId (id
, itemMenu
)))
793 void wxMenuBar::SetHelpString (int id
, const wxString
& helpString
)
796 for (i
= 0; i
< m_menuCount
; i
++)
798 if (m_menus
[i
]->FindItemForId (id
))
800 m_menus
[i
]->SetHelpString (id
, helpString
);
806 wxString
wxMenuBar::GetHelpString (int id
) const
809 for (i
= 0; i
< m_menuCount
; i
++)
811 if (m_menus
[i
]->FindItemForId (id
))
812 return wxString(m_menus
[i
]->GetHelpString (id
));
818 bool wxMenuBar::CreateMenuBar(wxFrame
* parent
)
822 XtVaSetValues((Widget
) parent
->GetMainWindowWidget(), XmNmenuBar
, (Widget
) m_mainWidget
, NULL
);
824 if (!XtIsManaged((Widget) m_mainWidget))
825 XtManageChild((Widget) m_mainWidget);
827 XtMapWidget((Widget
) m_mainWidget
);
831 Widget menuBarW
= XmCreateMenuBar ((Widget
) parent
->GetMainWindowWidget(), "MenuBar", NULL
, 0);
832 m_mainWidget
= (WXWidget
) menuBarW
;
835 for (i
= 0; i
< GetMenuCount(); i
++)
837 wxMenu
*menu
= GetMenu(i
);
838 wxString
title(m_titles
[i
]);
839 menu
->SetButtonWidget(menu
->CreateMenu (this, menuBarW
, menu
, title
, TRUE
));
842 * COMMENT THIS OUT IF YOU DON'T LIKE A RIGHT-JUSTIFIED HELP MENU
844 wxStripMenuCodes ((char*) (const char*) title
, wxBuffer
);
846 if (strcmp (wxBuffer
, "Help") == 0)
847 XtVaSetValues ((Widget
) menuBarW
, XmNmenuHelpWidget
, (Widget
) menu
->GetButtonWidget(), NULL
);
850 SetBackgroundColour(m_backgroundColour
);
851 SetForegroundColour(m_foregroundColour
);
854 XtVaSetValues((Widget
) parent
->GetMainWindowWidget(), XmNmenuBar
, (Widget
) m_mainWidget
, NULL
);
855 XtRealizeWidget ((Widget
) menuBarW
);
856 XtManageChild ((Widget
) menuBarW
);
857 SetMenuBarFrame(parent
);
862 // Destroy menubar, but keep data structures intact so we can recreate it.
863 bool wxMenuBar::DestroyMenuBar()
867 SetMenuBarFrame((wxFrame
*) NULL
);
871 XtUnmanageChild ((Widget
) m_mainWidget
);
872 XtUnrealizeWidget ((Widget
) m_mainWidget
);
875 for (i
= 0; i
< GetMenuCount(); i
++)
877 wxMenu
*menu
= GetMenu(i
);
878 menu
->DestroyMenu(TRUE
);
881 XtDestroyWidget((Widget
) m_mainWidget
);
882 m_mainWidget
= (WXWidget
) 0;
884 SetMenuBarFrame((wxFrame
*) NULL
);
891 extern wxApp
*wxTheApp
;
892 static XtWorkProcId WorkProcMenuId
;
894 /* Since PopupMenu under Motif stills grab right mouse button events
895 * after it was closed, we need to delete the associated widgets to
896 * allow next PopUpMenu to appear...
899 int PostDeletionOfMenu( XtPointer
* clientData
)
901 XtRemoveWorkProc(WorkProcMenuId
);
902 wxMenu
*menu
= (wxMenu
*)clientData
;
904 if (menu
->GetMainWidget()) {
905 if (menu
->GetParent())
907 wxList
& list
= menu
->GetParent()->GetItems();
908 list
.DeleteObject(menu
);
910 menu
->DestroyMenu(TRUE
);
912 /* Mark as no longer popped up */
918 wxMenuPopdownCallback(Widget w
, XtPointer clientData
,
921 wxMenu
*menu
= (wxMenu
*)clientData
;
923 // Added by JOREL Jean-Charles <jjorel@silr.ireste.fr>
924 /* Since Callbacks of MenuItems are not yet processed, we put a
925 * background job which will be done when system will be idle.
926 * What awful hack!! :(
929 WorkProcMenuId
= XtAppAddWorkProc(
930 (XtAppContext
) wxTheApp
->GetAppContext(),
931 (XtWorkProc
) PostDeletionOfMenu
,
933 // Apparently not found in Motif headers
934 // XtVaSetValues( w, XmNpopupEnabled, XmPOPUP_DISABLED, NULL );
938 * Create a popup or pulldown menu.
939 * Submenus of a popup will be pulldown.
943 WXWidget
wxMenu::CreateMenu (wxMenuBar
* menuBar
, WXWidget parent
, wxMenu
* topMenu
, const wxString
& title
, bool pullDown
)
945 Widget menu
= (Widget
) 0;
946 Widget buttonWidget
= (Widget
) 0;
948 XtSetArg (args
[0], XmNnumColumns
, m_numColumns
);
949 XtSetArg (args
[1], XmNpacking
, XmPACK_COLUMN
);
953 menu
= XmCreatePopupMenu ((Widget
) parent
, "popup", args
, 2);
956 (XtCallbackProc
)wxMenuPopdownCallback
,
961 char mnem
= wxFindMnemonic (title
);
962 wxStripMenuCodes ((char*) (const char*) title
, wxBuffer
);
964 menu
= XmCreatePulldownMenu ((Widget
) parent
, "pulldown", args
, 2);
966 XmString label_str
= XmStringCreateSimple (wxBuffer
);
967 buttonWidget
= XtVaCreateManagedWidget (wxBuffer
,
969 xmCascadeButtonGadgetClass
, (Widget
) parent
,
971 xmCascadeButtonWidgetClass
, (Widget
) parent
,
973 XmNlabelString
, label_str
,
978 XtVaSetValues (buttonWidget
, XmNmnemonic
, mnem
, NULL
);
980 XmStringFree (label_str
);
983 m_menuWidget
= (WXWidget
) menu
;
986 m_topLevelMenu
= topMenu
;
988 for (wxNode
* node
= m_menuItems
.First (); node
; node
= node
->Next ())
990 wxMenuItem
*item
= (wxMenuItem
*) node
->Data ();
991 item
->CreateItem (menu
, menuBar
, topMenu
);
994 SetBackgroundColour(m_backgroundColour
);
995 SetForegroundColour(m_foregroundColour
);
1001 // Destroys the Motif implementation of the menu,
1002 // but maintains the wxWindows data structures so we can
1003 // do a CreateMenu again.
1004 void wxMenu::DestroyMenu (bool full
)
1006 for (wxNode
* node
= m_menuItems
.First (); node
; node
= node
->Next ())
1008 wxMenuItem
*item
= (wxMenuItem
*) node
->Data ();
1009 item
->SetMenuBar((wxMenuBar
*) NULL
);
1011 item
->DestroyItem(full
);
1018 XtVaSetValues((Widget
) m_buttonWidget
, XmNsubMenuId
, NULL
, NULL
);
1019 XtDestroyWidget ((Widget
) m_buttonWidget
);
1020 m_buttonWidget
= (WXWidget
) 0;
1023 if (m_menuWidget
&& full
)
1025 XtDestroyWidget((Widget
) m_menuWidget
);
1026 m_menuWidget
= (WXWidget
) NULL
;
1030 WXWidget
wxMenu::FindMenuItem (int id
, wxMenuItem
** it
) const
1035 *it
= (wxMenuItem
*) NULL
;
1036 return m_buttonWidget
;
1039 for (wxNode
* node
= m_menuItems
.First (); node
; node
= node
->Next ())
1041 wxMenuItem
*item
= (wxMenuItem
*) node
->Data ();
1042 if (item
->GetId() == id
)
1046 return item
->GetButtonWidget();
1049 if (item
->GetSubMenu())
1051 WXWidget w
= item
->GetSubMenu()->FindMenuItem (id
, it
);
1060 *it
= (wxMenuItem
*) NULL
;
1061 return (WXWidget
) NULL
;
1064 void wxMenu::SetBackgroundColour(const wxColour
& col
)
1066 m_backgroundColour
= col
;
1068 wxDoChangeBackgroundColour(m_menuWidget
, (wxColour
&) col
);
1070 wxDoChangeBackgroundColour(m_buttonWidget
, (wxColour
&) col
, TRUE
);
1072 wxNode
* node
= m_menuItems
.First();
1075 wxMenuItem
* item
= (wxMenuItem
*) node
->Data();
1076 if (item
->GetButtonWidget())
1078 // This crashes because it uses gadgets
1079 // wxDoChangeBackgroundColour(item->GetButtonWidget(), (wxColour&) col, TRUE);
1081 if (item
->GetSubMenu())
1082 item
->GetSubMenu()->SetBackgroundColour((wxColour
&) col
);
1083 node
= node
->Next();
1087 void wxMenu::SetForegroundColour(const wxColour
& col
)
1089 m_foregroundColour
= col
;
1091 wxDoChangeForegroundColour(m_menuWidget
, (wxColour
&) col
);
1093 wxDoChangeForegroundColour(m_buttonWidget
, (wxColour
&) col
);
1095 wxNode
* node
= m_menuItems
.First();
1098 wxMenuItem
* item
= (wxMenuItem
*) node
->Data();
1099 if (item
->GetButtonWidget())
1101 // This crashes because it uses gadgets
1102 // wxDoChangeForegroundColour(item->GetButtonWidget(), (wxColour&) col);
1104 if (item
->GetSubMenu())
1105 item
->GetSubMenu()->SetForegroundColour((wxColour
&) col
);
1106 node
= node
->Next();
1110 void wxMenu::ChangeFont(bool keepOriginalSize
)
1112 // lesstif 0.87 hangs when setting XmNfontList
1113 #ifndef LESSTIF_VERSION
1114 if (!m_font
.Ok() || !m_menuWidget
)
1117 XmFontList fontList
= (XmFontList
) m_font
.GetFontList(1.0, XtDisplay((Widget
) m_menuWidget
));
1119 XtVaSetValues ((Widget
) m_menuWidget
,
1120 XmNfontList
, fontList
,
1124 XtVaSetValues ((Widget
) m_buttonWidget
,
1125 XmNfontList
, fontList
,
1128 wxNode
* node
= m_menuItems
.First();
1131 wxMenuItem
* item
= (wxMenuItem
*) node
->Data();
1132 if (m_menuWidget
&& item
->GetButtonWidget() && m_font
.Ok())
1134 XtVaSetValues ((Widget
) item
->GetButtonWidget(),
1135 XmNfontList
, fontList
,
1138 if (item
->GetSubMenu())
1139 item
->GetSubMenu()->ChangeFont(keepOriginalSize
);
1140 node
= node
->Next();
1145 void wxMenu::SetFont(const wxFont
& font
)
1151 void wxMenuBar::SetBackgroundColour(const wxColour
& col
)
1154 m_backgroundColour
= col
;
1156 wxDoChangeBackgroundColour(m_mainWidget
, (wxColour
&) col
);
1158 for (i
= 0; i
< m_menuCount
; i
++)
1159 m_menus
[i
]->SetBackgroundColour((wxColour
&) col
);
1162 void wxMenuBar::SetForegroundColour(const wxColour
& col
)
1164 m_foregroundColour
= col
;
1166 wxDoChangeForegroundColour(m_mainWidget
, (wxColour
&) col
);
1169 for (i
= 0; i
< m_menuCount
; i
++)
1170 m_menus
[i
]->SetForegroundColour((wxColour
&) col
);
1173 void wxMenuBar::ChangeFont(bool keepOriginalSize
)
1175 // Nothing to do for menubar, fonts are kept in wxMenus
1178 void wxMenuBar::SetFont(const wxFont
& font
)
1184 for (i
= 0; i
< m_menuCount
; i
++)
1185 m_menus
[i
]->SetFont(font
);