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 #include <Xm/LabelG.h>
31 #include <Xm/CascadeBG.h>
32 #include <Xm/CascadeB.h>
33 #include <Xm/SeparatoG.h>
34 #include <Xm/PushBG.h>
35 #include <Xm/ToggleB.h>
36 #include <Xm/ToggleBG.h>
37 #include <Xm/RowColumn.h>
39 #include "wx/motif/private.h"
41 // ----------------------------------------------------------------------------
42 // functions prototypes
43 // ----------------------------------------------------------------------------
45 static void wxMenuItemCallback(Widget w
, XtPointer clientData
, XtPointer ptr
);
46 static void wxMenuItemArmCallback(Widget w
, XtPointer clientData
, XtPointer ptr
);
47 static void wxMenuItemDisarmCallback(Widget w
, XtPointer clientData
, XtPointer ptr
);
49 // ============================================================================
51 // ============================================================================
53 // ----------------------------------------------------------------------------
54 // dynamic classes implementation
55 // ----------------------------------------------------------------------------
57 #if !USE_SHARED_LIBRARY
58 IMPLEMENT_DYNAMIC_CLASS(wxMenuItem
, wxObject
)
59 #endif //USE_SHARED_LIBRARY
61 // ----------------------------------------------------------------------------
63 // ----------------------------------------------------------------------------
68 wxMenuItem::wxMenuItem(wxMenu
*pParentMenu
, int id
,
69 const wxString
& strName
, const wxString
& strHelp
,
73 wxASSERT_MSG( pParentMenu
!= NULL
, wxT("menuitem should have a menu") );
76 m_parentMenu
= pParentMenu
;
82 m_isCheckable
= bCheckable
;
87 m_buttonWidget
= (WXWidget
) NULL
;
91 wxMenuItem::~wxMenuItem()
98 // delete the sub menu
99 void wxMenuItem::DeleteSubMenu()
101 wxASSERT( m_subMenu
!= NULL
);
110 void wxMenuItem::Enable(bool bDoEnable
)
112 if ( m_isChecked
!= bDoEnable
)
118 XtSetSensitive( (Widget
) m_buttonWidget
, (Boolean
) bDoEnable
);
122 // Maybe we should apply this to all items in the submenu?
123 // Or perhaps it works anyway.
125 XtSetSensitive( (Widget
) m_buttonWidget
, (Boolean
) bDoEnable
);
128 wxMenuItemBase::Enable(bDoEnable
);
132 void wxMenuItem::Check(bool bDoCheck
)
134 wxCHECK_RET( IsCheckable(), "only checkable items may be checked" );
136 if ( m_isChecked
!= bDoCheck
)
138 if ( m_buttonWidget
)
140 wxASSERT_MSG( XtIsSubclass((Widget
)m_buttonWidget
,
141 xmToggleButtonGadgetClass
),
142 wxT("checkable menu item must be a toggle button") );
144 XtVaSetValues((Widget
)m_buttonWidget
,
145 XmNset
, (Boolean
)bDoCheck
,
149 wxMenuItemBase::Check(bDoCheck
);
155 void wxMenuItem::CreateItem (WXWidget menu
, wxMenuBar
* menuBar
, wxMenu
* topMenu
)
162 // Id=-2 identifies a Title item.
163 m_buttonWidget
= (WXWidget
) XtVaCreateManagedWidget
164 (wxStripMenuCodes(m_text
),
165 xmLabelGadgetClass
, (Widget
) menu
, NULL
);
167 else if ((!m_text
.IsNull() && m_text
!= "") && (!m_subMenu
))
169 wxString strName
= wxStripMenuCodes(m_text
);
172 m_buttonWidget
= (WXWidget
) XtVaCreateManagedWidget (strName
,
173 xmToggleButtonGadgetClass
, (Widget
) menu
,
175 XtVaSetValues ((Widget
) m_buttonWidget
, XmNset
, (Boolean
) IsChecked(), NULL
);
178 m_buttonWidget
= (WXWidget
) XtVaCreateManagedWidget (strName
,
179 xmPushButtonGadgetClass
, (Widget
) menu
,
181 char mnem
= wxFindMnemonic (m_text
);
183 XtVaSetValues ((Widget
) m_buttonWidget
, XmNmnemonic
, mnem
, NULL
);
185 //// TODO: proper accelerator treatment. What does wxFindAccelerator
188 char *accel
= wxFindAccelerator (strName
);
190 XtVaSetValues ((Widget
) m_buttonWidget
, XmNaccelerator
, accel
, NULL
);
192 // TODO: What does this do?
193 XmString accel_str
= wxFindAcceleratorText (strName
);
196 XtVaSetValues ((Widget
) m_buttonWidget
, XmNacceleratorText
, accel_str
, NULL
);
197 XmStringFree (accel_str
);
201 XtAddCallback ((Widget
) m_buttonWidget
,
202 XmNvalueChangedCallback
,
203 (XtCallbackProc
) wxMenuItemCallback
,
206 XtAddCallback ((Widget
) m_buttonWidget
,
208 (XtCallbackProc
) wxMenuItemCallback
,
210 XtAddCallback ((Widget
) m_buttonWidget
,
212 (XtCallbackProc
) wxMenuItemArmCallback
,
214 XtAddCallback ((Widget
) m_buttonWidget
,
216 (XtCallbackProc
) wxMenuItemDisarmCallback
,
219 else if (GetId() == -1)
221 m_buttonWidget
= (WXWidget
) XtVaCreateManagedWidget ("separator",
222 xmSeparatorGadgetClass
, (Widget
) menu
, NULL
);
226 m_buttonWidget
= m_subMenu
->CreateMenu (menuBar
, menu
, topMenu
, m_text
, TRUE
);
227 m_subMenu
->SetButtonWidget(m_buttonWidget
);
228 XtAddCallback ((Widget
) m_buttonWidget
,
229 XmNcascadingCallback
,
230 (XtCallbackProc
) wxMenuItemArmCallback
,
234 XtSetSensitive ((Widget
) m_buttonWidget
, (Boolean
) IsEnabled());
237 void wxMenuItem::DestroyItem(bool full
)
244 else if ((!m_text
.IsNull() && (m_text
!= "")) && !m_subMenu
)
249 XtRemoveCallback ((Widget
) m_buttonWidget
, XmNvalueChangedCallback
,
250 wxMenuItemCallback
, (XtPointer
) this);
252 XtRemoveCallback ((Widget
) m_buttonWidget
, XmNactivateCallback
,
253 wxMenuItemCallback
, (XtPointer
) this);
254 XtRemoveCallback ((Widget
) m_buttonWidget
, XmNarmCallback
,
255 wxMenuItemArmCallback
, (XtPointer
) this);
256 XtRemoveCallback ((Widget
) m_buttonWidget
, XmNdisarmCallback
,
257 wxMenuItemDisarmCallback
, (XtPointer
) this);
260 else if (GetId() == -1)
265 else if (GetSubMenu())
269 XtRemoveCallback ((Widget
) m_buttonWidget
, XmNcascadingCallback
,
270 wxMenuItemArmCallback
, (XtPointer
) this);
272 m_subMenu
->DestroyMenu(full
);
274 m_buttonWidget
= NULL
;
277 if (m_buttonWidget
&& full
)
279 XtDestroyWidget ((Widget
) m_buttonWidget
);
280 m_buttonWidget
= (WXWidget
) 0;
284 void wxMenuItem::SetText(const wxString
& label
)
286 char mnem
= wxFindMnemonic (label
);
287 wxString label2
= wxStripMenuCodes(label
);
293 wxXmString
label_str(label2
);
294 XtVaSetValues ((Widget
) m_buttonWidget
,
295 XmNlabelString
, label_str
,
298 XtVaSetValues ((Widget
) m_buttonWidget
, XmNmnemonic
, mnem
, NULL
);
299 char *accel
= wxFindAccelerator (label2
);
301 XtVaSetValues ((Widget
) m_buttonWidget
, XmNaccelerator
, accel
, NULL
);
303 XmString accel_str
= wxFindAcceleratorText (label2
);
306 XtVaSetValues ((Widget
) m_buttonWidget
, XmNacceleratorText
, accel_str
, NULL
);
307 XmStringFree (accel_str
);
312 // ----------------------------------------------------------------------------
314 // ----------------------------------------------------------------------------
316 void wxMenuItemCallback (Widget
WXUNUSED(w
), XtPointer clientData
,
317 XtPointer
WXUNUSED(ptr
))
319 wxMenuItem
*item
= (wxMenuItem
*) clientData
;
322 if (item
->IsCheckable())
324 Boolean isChecked
= FALSE
;
325 XtVaGetValues ((Widget
) item
->GetButtonWidget(), XmNset
, & isChecked
, NULL
);
327 // only set the flag, don't actually check anything
328 item
->wxMenuItemBase::Check(isChecked
);
330 if (item
->GetMenuBar() && item
->GetMenuBar()->GetMenuBarFrame())
332 wxCommandEvent
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, item
->GetId());
333 commandEvent
.SetEventObject(item
->GetMenuBar()->GetMenuBarFrame());
334 commandEvent
.SetInt( item
->GetId() );
336 item
->GetMenuBar()->GetMenuBarFrame()->GetEventHandler()->ProcessEvent(commandEvent
);
338 else if (item
->GetTopMenu())
340 wxCommandEvent
event (wxEVT_COMMAND_MENU_SELECTED
, item
->GetId());
341 event
.SetEventObject(item
->GetTopMenu());
342 event
.SetInt( item
->GetId() );
344 item
->GetTopMenu()->ProcessCommand (event
);
349 void wxMenuItemArmCallback (Widget
WXUNUSED(w
), XtPointer clientData
,
350 XtPointer
WXUNUSED(ptr
))
352 wxMenuItem
*item
= (wxMenuItem
*) clientData
;
355 if (item
->GetMenuBar() && item
->GetMenuBar()->GetMenuBarFrame())
357 wxMenuEvent
menuEvent(wxEVT_MENU_HIGHLIGHT
, item
->GetId());
358 menuEvent
.SetEventObject(item
->GetMenuBar()->GetMenuBarFrame());
360 item
->GetMenuBar()->GetMenuBarFrame()->GetEventHandler()->ProcessEvent(menuEvent
);
366 wxMenuItemDisarmCallback (Widget
WXUNUSED(w
), XtPointer clientData
,
367 XtPointer
WXUNUSED(ptr
))
369 wxMenuItem
*item
= (wxMenuItem
*) clientData
;
372 if (item
->GetMenuBar() && item
->GetMenuBar()->GetMenuBarFrame())
374 // TODO: not sure this is correct, since -1 means something
375 // special to event system
376 wxMenuEvent
menuEvent(wxEVT_MENU_HIGHLIGHT
, -1);
377 menuEvent
.SetEventObject(item
->GetMenuBar()->GetMenuBarFrame());
379 item
->GetMenuBar()->GetMenuBarFrame()->GetEventHandler()->ProcessEvent(menuEvent
);