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 #if !USE_SHARED_LIBRARY
64 IMPLEMENT_DYNAMIC_CLASS(wxMenuItem
, wxObject
)
65 #endif //USE_SHARED_LIBRARY
67 // ----------------------------------------------------------------------------
69 // ----------------------------------------------------------------------------
74 wxMenuItem::wxMenuItem(wxMenu
*pParentMenu
, int id
,
75 const wxString
& strName
, const wxString
& strHelp
,
79 wxASSERT_MSG( pParentMenu
!= NULL
, wxT("menuitem should have a menu") );
82 m_parentMenu
= pParentMenu
;
88 m_isCheckable
= bCheckable
;
93 m_buttonWidget
= (WXWidget
) NULL
;
97 wxMenuItem::~wxMenuItem()
104 // delete the sub menu
105 void wxMenuItem::DeleteSubMenu()
107 wxASSERT( m_subMenu
!= NULL
);
116 void wxMenuItem::Enable(bool bDoEnable
)
118 if ( m_isChecked
!= bDoEnable
)
124 XtSetSensitive( (Widget
) m_buttonWidget
, (Boolean
) bDoEnable
);
128 // Maybe we should apply this to all items in the submenu?
129 // Or perhaps it works anyway.
131 XtSetSensitive( (Widget
) m_buttonWidget
, (Boolean
) bDoEnable
);
134 wxMenuItemBase::Enable(bDoEnable
);
138 void wxMenuItem::Check(bool bDoCheck
)
140 wxCHECK_RET( IsCheckable(), "only checkable items may be checked" );
142 if ( m_isChecked
!= bDoCheck
)
144 if ( m_buttonWidget
)
146 wxASSERT_MSG( XtIsSubclass((Widget
)m_buttonWidget
,
147 xmToggleButtonGadgetClass
),
148 wxT("checkable menu item must be a toggle button") );
150 XtVaSetValues((Widget
)m_buttonWidget
,
151 XmNset
, (Boolean
)bDoCheck
,
155 wxMenuItemBase::Check(bDoCheck
);
159 wxString
wxMenuItem::GetLabel() const
161 return wxStripMenuCodes(m_text
);
165 // ----------------------------------------------------------------------------
167 // ----------------------------------------------------------------------------
169 wxMenuItem
*wxMenuItemBase::New(wxMenu
*parentMenu
,
171 const wxString
& name
,
172 const wxString
& help
,
176 return new wxMenuItem(parentMenu
, id
, name
, help
, isCheckable
, subMenu
);
179 // ----------------------------------------------------------------------------
181 // ----------------------------------------------------------------------------
183 void wxMenuItem::CreateItem (WXWidget menu
, wxMenuBar
* menuBar
, wxMenu
* topMenu
)
190 // Id=-2 identifies a Title item.
191 m_buttonWidget
= (WXWidget
) XtVaCreateManagedWidget
192 (wxStripMenuCodes(m_text
),
193 xmLabelGadgetClass
, (Widget
) menu
, NULL
);
195 else if ((!m_text
.IsNull() && m_text
!= "") && (!m_subMenu
))
197 wxString strName
= wxStripMenuCodes(m_text
);
200 m_buttonWidget
= (WXWidget
) XtVaCreateManagedWidget (strName
,
201 xmToggleButtonGadgetClass
, (Widget
) menu
,
203 XtVaSetValues ((Widget
) m_buttonWidget
, XmNset
, (Boolean
) IsChecked(), NULL
);
206 m_buttonWidget
= (WXWidget
) XtVaCreateManagedWidget (strName
,
207 xmPushButtonGadgetClass
, (Widget
) menu
,
209 char mnem
= wxFindMnemonic (m_text
);
211 XtVaSetValues ((Widget
) m_buttonWidget
, XmNmnemonic
, mnem
, NULL
);
213 //// TODO: proper accelerator treatment. What does wxFindAccelerator
216 char *accel
= wxFindAccelerator (strName
);
218 XtVaSetValues ((Widget
) m_buttonWidget
, XmNaccelerator
, accel
, NULL
);
220 // TODO: What does this do?
221 XmString accel_str
= wxFindAcceleratorText (strName
);
224 XtVaSetValues ((Widget
) m_buttonWidget
, XmNacceleratorText
, accel_str
, NULL
);
225 XmStringFree (accel_str
);
229 XtAddCallback ((Widget
) m_buttonWidget
,
230 XmNvalueChangedCallback
,
231 (XtCallbackProc
) wxMenuItemCallback
,
234 XtAddCallback ((Widget
) m_buttonWidget
,
236 (XtCallbackProc
) wxMenuItemCallback
,
238 XtAddCallback ((Widget
) m_buttonWidget
,
240 (XtCallbackProc
) wxMenuItemArmCallback
,
242 XtAddCallback ((Widget
) m_buttonWidget
,
244 (XtCallbackProc
) wxMenuItemDisarmCallback
,
247 else if (GetId() == -1)
249 m_buttonWidget
= (WXWidget
) XtVaCreateManagedWidget ("separator",
250 xmSeparatorGadgetClass
, (Widget
) menu
, NULL
);
254 m_buttonWidget
= m_subMenu
->CreateMenu (menuBar
, menu
, topMenu
, m_text
, TRUE
);
255 m_subMenu
->SetButtonWidget(m_buttonWidget
);
256 XtAddCallback ((Widget
) m_buttonWidget
,
257 XmNcascadingCallback
,
258 (XtCallbackProc
) wxMenuItemArmCallback
,
262 XtSetSensitive ((Widget
) m_buttonWidget
, (Boolean
) IsEnabled());
265 void wxMenuItem::DestroyItem(bool full
)
272 else if ((!m_text
.IsNull() && (m_text
!= "")) && !m_subMenu
)
277 XtRemoveCallback ((Widget
) m_buttonWidget
, XmNvalueChangedCallback
,
278 wxMenuItemCallback
, (XtPointer
) this);
280 XtRemoveCallback ((Widget
) m_buttonWidget
, XmNactivateCallback
,
281 wxMenuItemCallback
, (XtPointer
) this);
282 XtRemoveCallback ((Widget
) m_buttonWidget
, XmNarmCallback
,
283 wxMenuItemArmCallback
, (XtPointer
) this);
284 XtRemoveCallback ((Widget
) m_buttonWidget
, XmNdisarmCallback
,
285 wxMenuItemDisarmCallback
, (XtPointer
) this);
288 else if (GetId() == -1)
293 else if (GetSubMenu())
297 XtRemoveCallback ((Widget
) m_buttonWidget
, XmNcascadingCallback
,
298 wxMenuItemArmCallback
, (XtPointer
) this);
300 m_subMenu
->DestroyMenu(full
);
302 m_buttonWidget
= NULL
;
305 if (m_buttonWidget
&& full
)
307 XtDestroyWidget ((Widget
) m_buttonWidget
);
308 m_buttonWidget
= (WXWidget
) 0;
312 void wxMenuItem::SetText(const wxString
& label
)
314 char mnem
= wxFindMnemonic (label
);
315 wxString label2
= wxStripMenuCodes(label
);
321 wxXmString
label_str(label2
);
322 XtVaSetValues ((Widget
) m_buttonWidget
,
323 XmNlabelString
, label_str(),
326 XtVaSetValues ((Widget
) m_buttonWidget
, XmNmnemonic
, mnem
, NULL
);
327 char *accel
= wxFindAccelerator (label2
);
329 XtVaSetValues ((Widget
) m_buttonWidget
, XmNaccelerator
, accel
, NULL
);
331 XmString accel_str
= wxFindAcceleratorText (label2
);
334 XtVaSetValues ((Widget
) m_buttonWidget
, XmNacceleratorText
, accel_str
, NULL
);
335 XmStringFree (accel_str
);
340 // ----------------------------------------------------------------------------
342 // ----------------------------------------------------------------------------
344 void wxMenuItemCallback (Widget
WXUNUSED(w
), XtPointer clientData
,
345 XtPointer
WXUNUSED(ptr
))
347 wxMenuItem
*item
= (wxMenuItem
*) clientData
;
350 if (item
->IsCheckable())
352 Boolean isChecked
= FALSE
;
353 XtVaGetValues ((Widget
) item
->GetButtonWidget(), XmNset
, & isChecked
, NULL
);
355 // only set the flag, don't actually check anything
356 item
->wxMenuItemBase::Check(isChecked
);
358 if (item
->GetMenuBar() && item
->GetMenuBar()->GetMenuBarFrame())
360 wxCommandEvent
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, item
->GetId());
361 commandEvent
.SetEventObject(item
->GetMenuBar()->GetMenuBarFrame());
362 commandEvent
.SetInt( item
->GetId() );
364 item
->GetMenuBar()->GetMenuBarFrame()->GetEventHandler()->ProcessEvent(commandEvent
);
366 else if (item
->GetTopMenu())
368 wxCommandEvent
event (wxEVT_COMMAND_MENU_SELECTED
, item
->GetId());
369 event
.SetEventObject(item
->GetTopMenu());
370 event
.SetInt( item
->GetId() );
372 item
->GetTopMenu()->ProcessCommand (event
);
377 void wxMenuItemArmCallback (Widget
WXUNUSED(w
), XtPointer clientData
,
378 XtPointer
WXUNUSED(ptr
))
380 wxMenuItem
*item
= (wxMenuItem
*) clientData
;
383 if (item
->GetMenuBar() && item
->GetMenuBar()->GetMenuBarFrame())
385 wxMenuEvent
menuEvent(wxEVT_MENU_HIGHLIGHT
, item
->GetId());
386 menuEvent
.SetEventObject(item
->GetMenuBar()->GetMenuBarFrame());
388 item
->GetMenuBar()->GetMenuBarFrame()->GetEventHandler()->ProcessEvent(menuEvent
);
394 wxMenuItemDisarmCallback (Widget
WXUNUSED(w
), XtPointer clientData
,
395 XtPointer
WXUNUSED(ptr
))
397 wxMenuItem
*item
= (wxMenuItem
*) clientData
;
400 if (item
->GetMenuBar() && item
->GetMenuBar()->GetMenuBarFrame())
402 // TODO: not sure this is correct, since -1 means something
403 // special to event system
404 wxMenuEvent
menuEvent(wxEVT_MENU_HIGHLIGHT
, -1);
405 menuEvent
.SetEventObject(item
->GetMenuBar()->GetMenuBarFrame());
407 item
->GetMenuBar()->GetMenuBarFrame()->GetEventHandler()->ProcessEvent(menuEvent
);