1 ///////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxMenuItem implementation
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
17 #pragma implementation "menuitem.h"
20 // ----------------------------------------------------------------------------
22 // ----------------------------------------------------------------------------
25 #include "wx/menuitem.h"
30 #pragma message disable nosimpint
33 #include <Xm/LabelG.h>
34 #include <Xm/CascadeBG.h>
35 #include <Xm/CascadeB.h>
36 #include <Xm/SeparatoG.h>
37 #include <Xm/PushBG.h>
38 #include <Xm/ToggleB.h>
39 #include <Xm/ToggleBG.h>
40 #include <Xm/RowColumn.h>
42 #pragma message enable nosimpint
45 #include "wx/motif/private.h"
47 // ----------------------------------------------------------------------------
48 // functions prototypes
49 // ----------------------------------------------------------------------------
51 static void wxMenuItemCallback(Widget w
, XtPointer clientData
, XtPointer ptr
);
52 static void wxMenuItemArmCallback(Widget w
, XtPointer clientData
, XtPointer ptr
);
53 static void wxMenuItemDisarmCallback(Widget w
, XtPointer clientData
, XtPointer ptr
);
55 // ============================================================================
57 // ============================================================================
59 // ----------------------------------------------------------------------------
60 // dynamic classes implementation
61 // ----------------------------------------------------------------------------
63 IMPLEMENT_DYNAMIC_CLASS(wxMenuItem
, wxObject
)
65 // ----------------------------------------------------------------------------
67 // ----------------------------------------------------------------------------
72 wxMenuItem::wxMenuItem(wxMenu
*pParentMenu
, int id
,
73 const wxString
& strName
, const wxString
& strHelp
,
77 wxASSERT_MSG( pParentMenu
!= NULL
, wxT("menuitem should have a menu") );
80 m_parentMenu
= pParentMenu
;
86 m_isCheckable
= bCheckable
;
91 m_buttonWidget
= (WXWidget
) NULL
;
95 wxMenuItem::~wxMenuItem()
102 // delete the sub menu
103 void wxMenuItem::DeleteSubMenu()
105 wxASSERT( m_subMenu
!= NULL
);
114 void wxMenuItem::Enable(bool bDoEnable
)
116 if ( m_isEnabled
!= bDoEnable
)
122 XtSetSensitive( (Widget
) m_buttonWidget
, (Boolean
) bDoEnable
);
126 // Maybe we should apply this to all items in the submenu?
127 // Or perhaps it works anyway.
129 XtSetSensitive( (Widget
) m_buttonWidget
, (Boolean
) bDoEnable
);
132 wxMenuItemBase::Enable(bDoEnable
);
136 void wxMenuItem::Check(bool bDoCheck
)
138 wxCHECK_RET( IsCheckable(), "only checkable items may be checked" );
140 if ( m_isChecked
!= bDoCheck
)
142 if ( m_buttonWidget
)
144 wxASSERT_MSG( XtIsSubclass((Widget
)m_buttonWidget
,
145 xmToggleButtonGadgetClass
),
146 wxT("checkable menu item must be a toggle button") );
148 XtVaSetValues((Widget
)m_buttonWidget
,
149 XmNset
, (Boolean
)bDoCheck
,
153 wxMenuItemBase::Check(bDoCheck
);
158 wxString
wxMenuItemBase::GetLabelFromText(const wxString
& text
)
160 return wxStripMenuCodes(text
);
163 // ----------------------------------------------------------------------------
165 // ----------------------------------------------------------------------------
167 wxMenuItem
*wxMenuItemBase::New(wxMenu
*parentMenu
,
169 const wxString
& name
,
170 const wxString
& help
,
174 return new wxMenuItem(parentMenu
, id
, name
, help
, isCheckable
, subMenu
);
177 // ----------------------------------------------------------------------------
179 // ----------------------------------------------------------------------------
181 void wxMenuItem::CreateItem (WXWidget menu
, wxMenuBar
* menuBar
, wxMenu
* topMenu
)
188 // Id=-2 identifies a Title item.
189 m_buttonWidget
= (WXWidget
) XtVaCreateManagedWidget
190 (wxStripMenuCodes(m_text
),
191 xmLabelGadgetClass
, (Widget
) menu
, NULL
);
193 else if ((!m_text
.IsNull() && m_text
!= "") && (!m_subMenu
))
195 wxString strName
= wxStripMenuCodes(m_text
);
198 m_buttonWidget
= (WXWidget
) XtVaCreateManagedWidget (strName
,
199 xmToggleButtonGadgetClass
, (Widget
) menu
,
201 XtVaSetValues ((Widget
) m_buttonWidget
, XmNset
, (Boolean
) IsChecked(), NULL
);
204 m_buttonWidget
= (WXWidget
) XtVaCreateManagedWidget (strName
,
205 xmPushButtonGadgetClass
, (Widget
) menu
,
207 char mnem
= wxFindMnemonic (m_text
);
209 XtVaSetValues ((Widget
) m_buttonWidget
, XmNmnemonic
, mnem
, NULL
);
211 //// TODO: proper accelerator treatment. What does wxFindAccelerator
214 char *accel
= wxFindAccelerator (strName
);
216 XtVaSetValues ((Widget
) m_buttonWidget
, XmNaccelerator
, accel
, NULL
);
218 // TODO: What does this do?
219 XmString accel_str
= wxFindAcceleratorText (strName
);
222 XtVaSetValues ((Widget
) m_buttonWidget
, XmNacceleratorText
, accel_str
, NULL
);
223 XmStringFree (accel_str
);
227 XtAddCallback ((Widget
) m_buttonWidget
,
228 XmNvalueChangedCallback
,
229 (XtCallbackProc
) wxMenuItemCallback
,
232 XtAddCallback ((Widget
) m_buttonWidget
,
234 (XtCallbackProc
) wxMenuItemCallback
,
236 XtAddCallback ((Widget
) m_buttonWidget
,
238 (XtCallbackProc
) wxMenuItemArmCallback
,
240 XtAddCallback ((Widget
) m_buttonWidget
,
242 (XtCallbackProc
) wxMenuItemDisarmCallback
,
245 else if (GetId() == -1)
247 m_buttonWidget
= (WXWidget
) XtVaCreateManagedWidget ("separator",
248 xmSeparatorGadgetClass
, (Widget
) menu
, NULL
);
252 m_buttonWidget
= m_subMenu
->CreateMenu (menuBar
, menu
, topMenu
, m_text
, TRUE
);
253 m_subMenu
->SetButtonWidget(m_buttonWidget
);
254 XtAddCallback ((Widget
) m_buttonWidget
,
255 XmNcascadingCallback
,
256 (XtCallbackProc
) wxMenuItemArmCallback
,
260 XtSetSensitive ((Widget
) m_buttonWidget
, (Boolean
) IsEnabled());
263 void wxMenuItem::DestroyItem(bool full
)
270 else if ((!m_text
.IsNull() && (m_text
!= "")) && !m_subMenu
)
275 XtRemoveCallback ((Widget
) m_buttonWidget
, XmNvalueChangedCallback
,
276 wxMenuItemCallback
, (XtPointer
) this);
278 XtRemoveCallback ((Widget
) m_buttonWidget
, XmNactivateCallback
,
279 wxMenuItemCallback
, (XtPointer
) this);
280 XtRemoveCallback ((Widget
) m_buttonWidget
, XmNarmCallback
,
281 wxMenuItemArmCallback
, (XtPointer
) this);
282 XtRemoveCallback ((Widget
) m_buttonWidget
, XmNdisarmCallback
,
283 wxMenuItemDisarmCallback
, (XtPointer
) this);
286 else if (GetId() == -1)
291 else if (GetSubMenu())
295 XtRemoveCallback ((Widget
) m_buttonWidget
, XmNcascadingCallback
,
296 wxMenuItemArmCallback
, (XtPointer
) this);
298 m_subMenu
->DestroyMenu(full
);
300 m_buttonWidget
= NULL
;
303 if (m_buttonWidget
&& full
)
305 XtDestroyWidget ((Widget
) m_buttonWidget
);
306 m_buttonWidget
= (WXWidget
) 0;
310 void wxMenuItem::SetText(const wxString
& label
)
312 char mnem
= wxFindMnemonic (label
);
313 wxString label2
= wxStripMenuCodes(label
);
319 wxXmString
label_str(label2
);
320 XtVaSetValues ((Widget
) m_buttonWidget
,
321 XmNlabelString
, label_str(),
324 XtVaSetValues ((Widget
) m_buttonWidget
, XmNmnemonic
, mnem
, NULL
);
325 char *accel
= wxFindAccelerator (label2
);
327 XtVaSetValues ((Widget
) m_buttonWidget
, XmNaccelerator
, accel
, NULL
);
329 XmString accel_str
= wxFindAcceleratorText (label2
);
332 XtVaSetValues ((Widget
) m_buttonWidget
, XmNacceleratorText
, accel_str
, NULL
);
333 XmStringFree (accel_str
);
338 // ----------------------------------------------------------------------------
340 // ----------------------------------------------------------------------------
342 void wxMenuItemCallback (Widget
WXUNUSED(w
), XtPointer clientData
,
343 XtPointer
WXUNUSED(ptr
))
345 wxMenuItem
*item
= (wxMenuItem
*) clientData
;
348 if (item
->IsCheckable())
350 Boolean isChecked
= FALSE
;
351 XtVaGetValues ((Widget
) item
->GetButtonWidget(), XmNset
, & isChecked
, NULL
);
353 // only set the flag, don't actually check anything
354 item
->wxMenuItemBase::Check(isChecked
);
356 if (item
->GetMenuBar() && item
->GetMenuBar()->GetMenuBarFrame())
358 wxCommandEvent
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, item
->GetId());
359 commandEvent
.SetEventObject(item
->GetMenuBar()->GetMenuBarFrame());
360 commandEvent
.SetInt( item
->GetId() );
362 item
->GetMenuBar()->GetMenuBarFrame()->GetEventHandler()->ProcessEvent(commandEvent
);
364 else if (item
->GetTopMenu())
366 wxCommandEvent
event (wxEVT_COMMAND_MENU_SELECTED
, item
->GetId());
367 event
.SetEventObject(item
->GetTopMenu());
368 event
.SetInt( item
->GetId() );
370 item
->GetTopMenu()->ProcessCommand (event
);
375 void wxMenuItemArmCallback (Widget
WXUNUSED(w
), XtPointer clientData
,
376 XtPointer
WXUNUSED(ptr
))
378 wxMenuItem
*item
= (wxMenuItem
*) clientData
;
381 if (item
->GetMenuBar() && item
->GetMenuBar()->GetMenuBarFrame())
383 wxMenuEvent
menuEvent(wxEVT_MENU_HIGHLIGHT
, item
->GetId());
384 menuEvent
.SetEventObject(item
->GetMenuBar()->GetMenuBarFrame());
386 item
->GetMenuBar()->GetMenuBarFrame()->GetEventHandler()->ProcessEvent(menuEvent
);
392 wxMenuItemDisarmCallback (Widget
WXUNUSED(w
), XtPointer clientData
,
393 XtPointer
WXUNUSED(ptr
))
395 wxMenuItem
*item
= (wxMenuItem
*) clientData
;
398 if (item
->GetMenuBar() && item
->GetMenuBar()->GetMenuBarFrame())
400 // TODO: not sure this is correct, since -1 means something
401 // special to event system
402 wxMenuEvent
menuEvent(wxEVT_MENU_HIGHLIGHT
, -1);
403 menuEvent
.SetEventObject(item
->GetMenuBar()->GetMenuBarFrame());
405 item
->GetMenuBar()->GetMenuBarFrame()->GetEventHandler()->ProcessEvent(menuEvent
);