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
);
153 wxString
wxMenuItem::GetLabel() const
155 return wxStripMenuCodes(m_text
);
159 // ----------------------------------------------------------------------------
161 // ----------------------------------------------------------------------------
163 wxMenuItem
*wxMenuItemBase::New(wxMenu
*parentMenu
,
165 const wxString
& name
,
166 const wxString
& help
,
170 return new wxMenuItem(parentMenu
, id
, name
, help
, isCheckable
, subMenu
);
173 // ----------------------------------------------------------------------------
175 // ----------------------------------------------------------------------------
177 void wxMenuItem::CreateItem (WXWidget menu
, wxMenuBar
* menuBar
, wxMenu
* topMenu
)
184 // Id=-2 identifies a Title item.
185 m_buttonWidget
= (WXWidget
) XtVaCreateManagedWidget
186 (wxStripMenuCodes(m_text
),
187 xmLabelGadgetClass
, (Widget
) menu
, NULL
);
189 else if ((!m_text
.IsNull() && m_text
!= "") && (!m_subMenu
))
191 wxString strName
= wxStripMenuCodes(m_text
);
194 m_buttonWidget
= (WXWidget
) XtVaCreateManagedWidget (strName
,
195 xmToggleButtonGadgetClass
, (Widget
) menu
,
197 XtVaSetValues ((Widget
) m_buttonWidget
, XmNset
, (Boolean
) IsChecked(), NULL
);
200 m_buttonWidget
= (WXWidget
) XtVaCreateManagedWidget (strName
,
201 xmPushButtonGadgetClass
, (Widget
) menu
,
203 char mnem
= wxFindMnemonic (m_text
);
205 XtVaSetValues ((Widget
) m_buttonWidget
, XmNmnemonic
, mnem
, NULL
);
207 //// TODO: proper accelerator treatment. What does wxFindAccelerator
210 char *accel
= wxFindAccelerator (strName
);
212 XtVaSetValues ((Widget
) m_buttonWidget
, XmNaccelerator
, accel
, NULL
);
214 // TODO: What does this do?
215 XmString accel_str
= wxFindAcceleratorText (strName
);
218 XtVaSetValues ((Widget
) m_buttonWidget
, XmNacceleratorText
, accel_str
, NULL
);
219 XmStringFree (accel_str
);
223 XtAddCallback ((Widget
) m_buttonWidget
,
224 XmNvalueChangedCallback
,
225 (XtCallbackProc
) wxMenuItemCallback
,
228 XtAddCallback ((Widget
) m_buttonWidget
,
230 (XtCallbackProc
) wxMenuItemCallback
,
232 XtAddCallback ((Widget
) m_buttonWidget
,
234 (XtCallbackProc
) wxMenuItemArmCallback
,
236 XtAddCallback ((Widget
) m_buttonWidget
,
238 (XtCallbackProc
) wxMenuItemDisarmCallback
,
241 else if (GetId() == -1)
243 m_buttonWidget
= (WXWidget
) XtVaCreateManagedWidget ("separator",
244 xmSeparatorGadgetClass
, (Widget
) menu
, NULL
);
248 m_buttonWidget
= m_subMenu
->CreateMenu (menuBar
, menu
, topMenu
, m_text
, TRUE
);
249 m_subMenu
->SetButtonWidget(m_buttonWidget
);
250 XtAddCallback ((Widget
) m_buttonWidget
,
251 XmNcascadingCallback
,
252 (XtCallbackProc
) wxMenuItemArmCallback
,
256 XtSetSensitive ((Widget
) m_buttonWidget
, (Boolean
) IsEnabled());
259 void wxMenuItem::DestroyItem(bool full
)
266 else if ((!m_text
.IsNull() && (m_text
!= "")) && !m_subMenu
)
271 XtRemoveCallback ((Widget
) m_buttonWidget
, XmNvalueChangedCallback
,
272 wxMenuItemCallback
, (XtPointer
) this);
274 XtRemoveCallback ((Widget
) m_buttonWidget
, XmNactivateCallback
,
275 wxMenuItemCallback
, (XtPointer
) this);
276 XtRemoveCallback ((Widget
) m_buttonWidget
, XmNarmCallback
,
277 wxMenuItemArmCallback
, (XtPointer
) this);
278 XtRemoveCallback ((Widget
) m_buttonWidget
, XmNdisarmCallback
,
279 wxMenuItemDisarmCallback
, (XtPointer
) this);
282 else if (GetId() == -1)
287 else if (GetSubMenu())
291 XtRemoveCallback ((Widget
) m_buttonWidget
, XmNcascadingCallback
,
292 wxMenuItemArmCallback
, (XtPointer
) this);
294 m_subMenu
->DestroyMenu(full
);
296 m_buttonWidget
= NULL
;
299 if (m_buttonWidget
&& full
)
301 XtDestroyWidget ((Widget
) m_buttonWidget
);
302 m_buttonWidget
= (WXWidget
) 0;
306 void wxMenuItem::SetText(const wxString
& label
)
308 char mnem
= wxFindMnemonic (label
);
309 wxString label2
= wxStripMenuCodes(label
);
315 wxXmString
label_str(label2
);
316 XtVaSetValues ((Widget
) m_buttonWidget
,
317 XmNlabelString
, label_str(),
320 XtVaSetValues ((Widget
) m_buttonWidget
, XmNmnemonic
, mnem
, NULL
);
321 char *accel
= wxFindAccelerator (label2
);
323 XtVaSetValues ((Widget
) m_buttonWidget
, XmNaccelerator
, accel
, NULL
);
325 XmString accel_str
= wxFindAcceleratorText (label2
);
328 XtVaSetValues ((Widget
) m_buttonWidget
, XmNacceleratorText
, accel_str
, NULL
);
329 XmStringFree (accel_str
);
334 // ----------------------------------------------------------------------------
336 // ----------------------------------------------------------------------------
338 void wxMenuItemCallback (Widget
WXUNUSED(w
), XtPointer clientData
,
339 XtPointer
WXUNUSED(ptr
))
341 wxMenuItem
*item
= (wxMenuItem
*) clientData
;
344 if (item
->IsCheckable())
346 Boolean isChecked
= FALSE
;
347 XtVaGetValues ((Widget
) item
->GetButtonWidget(), XmNset
, & isChecked
, NULL
);
349 // only set the flag, don't actually check anything
350 item
->wxMenuItemBase::Check(isChecked
);
352 if (item
->GetMenuBar() && item
->GetMenuBar()->GetMenuBarFrame())
354 wxCommandEvent
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, item
->GetId());
355 commandEvent
.SetEventObject(item
->GetMenuBar()->GetMenuBarFrame());
356 commandEvent
.SetInt( item
->GetId() );
358 item
->GetMenuBar()->GetMenuBarFrame()->GetEventHandler()->ProcessEvent(commandEvent
);
360 else if (item
->GetTopMenu())
362 wxCommandEvent
event (wxEVT_COMMAND_MENU_SELECTED
, item
->GetId());
363 event
.SetEventObject(item
->GetTopMenu());
364 event
.SetInt( item
->GetId() );
366 item
->GetTopMenu()->ProcessCommand (event
);
371 void wxMenuItemArmCallback (Widget
WXUNUSED(w
), XtPointer clientData
,
372 XtPointer
WXUNUSED(ptr
))
374 wxMenuItem
*item
= (wxMenuItem
*) clientData
;
377 if (item
->GetMenuBar() && item
->GetMenuBar()->GetMenuBarFrame())
379 wxMenuEvent
menuEvent(wxEVT_MENU_HIGHLIGHT
, item
->GetId());
380 menuEvent
.SetEventObject(item
->GetMenuBar()->GetMenuBarFrame());
382 item
->GetMenuBar()->GetMenuBarFrame()->GetEventHandler()->ProcessEvent(menuEvent
);
388 wxMenuItemDisarmCallback (Widget
WXUNUSED(w
), XtPointer clientData
,
389 XtPointer
WXUNUSED(ptr
))
391 wxMenuItem
*item
= (wxMenuItem
*) clientData
;
394 if (item
->GetMenuBar() && item
->GetMenuBar()->GetMenuBarFrame())
396 // TODO: not sure this is correct, since -1 means something
397 // special to event system
398 wxMenuEvent
menuEvent(wxEVT_MENU_HIGHLIGHT
, -1);
399 menuEvent
.SetEventObject(item
->GetMenuBar()->GetMenuBarFrame());
401 item
->GetMenuBar()->GetMenuBarFrame()->GetEventHandler()->ProcessEvent(menuEvent
);