]> git.saurik.com Git - wxWidgets.git/blame - src/motif/menuitem.cpp
Fixed some compile errors (MSVC++ 6) and some very strange link errors when
[wxWidgets.git] / src / motif / menuitem.cpp
CommitLineData
4bb6408c
JS
1///////////////////////////////////////////////////////////////////////////////
2// Name: menuitem.cpp
3// Purpose: wxMenuItem implementation
4// Author: Julian Smart
5// Modified by:
6// Created: 17/09/98
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart
9// Licence: wxWindows licence
10///////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// headers & declarations
14// ============================================================================
15
16#include "wx/menu.h"
17#include "wx/menuitem.h"
50414e24
JS
18#include "wx/utils.h"
19#include "wx/frame.h"
20
21#include <Xm/Label.h>
22#include <Xm/LabelG.h>
23#include <Xm/CascadeBG.h>
24#include <Xm/CascadeB.h>
25#include <Xm/SeparatoG.h>
26#include <Xm/PushBG.h>
27#include <Xm/ToggleB.h>
28#include <Xm/ToggleBG.h>
29#include <Xm/RowColumn.h>
30
31#include "wx/motif/private.h"
32
33void wxMenuItemCallback (Widget w, XtPointer clientData,
2d120f83 34 XtPointer ptr);
50414e24 35void wxMenuItemArmCallback (Widget w, XtPointer clientData,
2d120f83 36 XtPointer ptr);
50414e24 37void wxMenuItemDisarmCallback (Widget w, XtPointer clientData,
2d120f83 38 XtPointer ptr);
4bb6408c
JS
39
40// ============================================================================
41// implementation
42// ============================================================================
43
44// ----------------------------------------------------------------------------
45// dynamic classes implementation
46// ----------------------------------------------------------------------------
47
48#if !USE_SHARED_LIBRARY
2d120f83 49IMPLEMENT_DYNAMIC_CLASS(wxMenuItem, wxObject)
4bb6408c
JS
50#endif //USE_SHARED_LIBRARY
51
52// ----------------------------------------------------------------------------
53// wxMenuItem
54// ----------------------------------------------------------------------------
55
56// ctor & dtor
57// -----------
58
59wxMenuItem::wxMenuItem(wxMenu *pParentMenu, int id,
60 const wxString& strName, const wxString& strHelp,
61 bool bCheckable,
62 wxMenu *pSubMenu) :
2d120f83
JS
63m_strHelp(strHelp),
64m_bCheckable(bCheckable),
65m_strName(strName)
4bb6408c 66{
2d120f83 67 wxASSERT( pParentMenu != NULL );
31528cd3 68
2d120f83
JS
69 m_pParentMenu = pParentMenu;
70 m_pSubMenu = pSubMenu;
71 m_idItem = id;
72 m_bEnabled = TRUE;
73 m_bChecked = FALSE;
31528cd3 74
2d120f83
JS
75 //// Motif-specific
76 m_menuBar = NULL;
77 m_buttonWidget = (WXWidget) NULL;
78 m_topMenu = NULL;
4bb6408c
JS
79}
80
31528cd3 81wxMenuItem::~wxMenuItem()
4bb6408c
JS
82{
83}
84
85// misc
86// ----
87
88// delete the sub menu
89void wxMenuItem::DeleteSubMenu()
90{
2d120f83 91 wxASSERT( m_pSubMenu != NULL );
31528cd3 92
2d120f83
JS
93 delete m_pSubMenu;
94 m_pSubMenu = NULL;
4bb6408c
JS
95}
96
97// change item state
98// -----------------
99
100void wxMenuItem::Enable(bool bDoEnable)
101{
2d120f83 102 if ( m_bEnabled != bDoEnable )
4bb6408c 103 {
2d120f83
JS
104 if ( m_pSubMenu == NULL )
105 { // normal menu item
106 if (m_buttonWidget)
107 XtSetSensitive( (Widget) m_buttonWidget, (Boolean) bDoEnable);
108 }
109 else // submenu
110 {
111 // Maybe we should apply this to all items in the submenu?
112 // Or perhaps it works anyway.
113 if (m_buttonWidget)
114 XtSetSensitive( (Widget) m_buttonWidget, (Boolean) bDoEnable);
115 }
31528cd3 116
2d120f83 117 m_bEnabled = bDoEnable;
4bb6408c 118 }
4bb6408c
JS
119}
120
121void wxMenuItem::Check(bool bDoCheck)
122{
2d120f83 123 wxCHECK_RET( IsCheckable(), "only checkable items may be checked" );
31528cd3 124
2d120f83 125 if ( m_bChecked != bDoCheck )
50414e24 126 {
2d120f83
JS
127 if (m_buttonWidget && XtIsSubclass ((Widget) m_buttonWidget, xmToggleButtonGadgetClass))
128 {
129 XtVaSetValues ( (Widget) m_buttonWidget, XmNset, (Boolean) bDoCheck, NULL);
130 }
131 m_bChecked = bDoCheck;
50414e24 132 }
50414e24
JS
133}
134
135//// Motif-specific
136
137void wxMenuItem::CreateItem (WXWidget menu, wxMenuBar * menuBar, wxMenu * topMenu)
138{
2d120f83
JS
139 m_menuBar = menuBar;
140 m_topMenu = topMenu;
31528cd3 141
2d120f83 142 if (GetId() == -2)
50414e24 143 {
2d120f83 144 // Id=-2 identifies a Title item.
31528cd3
VZ
145 m_buttonWidget = (WXWidget) XtVaCreateManagedWidget
146 (wxStripMenuCodes(m_strName),
2d120f83 147 xmLabelGadgetClass, (Widget) menu, NULL);
50414e24 148 }
2d120f83 149 else if ((!m_strName.IsNull() && m_strName != "") && (!m_pSubMenu))
50414e24 150 {
31528cd3 151 wxString strName = wxStripMenuCodes(m_strName);
2d120f83
JS
152 if (IsCheckable())
153 {
31528cd3 154 m_buttonWidget = (WXWidget) XtVaCreateManagedWidget (strName,
2d120f83
JS
155 xmToggleButtonGadgetClass, (Widget) menu,
156 NULL);
157 XtVaSetValues ((Widget) m_buttonWidget, XmNset, (Boolean) IsChecked(), NULL);
158 }
159 else
31528cd3 160 m_buttonWidget = (WXWidget) XtVaCreateManagedWidget (strName,
2d120f83
JS
161 xmPushButtonGadgetClass, (Widget) menu,
162 NULL);
163 char mnem = wxFindMnemonic (m_strName);
164 if (mnem != 0)
165 XtVaSetValues ((Widget) m_buttonWidget, XmNmnemonic, mnem, NULL);
31528cd3 166
2d120f83
JS
167 //// TODO: proper accelerator treatment. What does wxFindAccelerator
168 //// look for?
31528cd3
VZ
169 strName = m_strName;
170 char *accel = wxFindAccelerator (strName);
2d120f83
JS
171 if (accel)
172 XtVaSetValues ((Widget) m_buttonWidget, XmNaccelerator, accel, NULL);
31528cd3 173
2d120f83 174 // TODO: What does this do?
31528cd3 175 XmString accel_str = wxFindAcceleratorText (strName);
2d120f83
JS
176 if (accel_str)
177 {
178 XtVaSetValues ((Widget) m_buttonWidget, XmNacceleratorText, accel_str, NULL);
179 XmStringFree (accel_str);
180 }
31528cd3 181
2d120f83
JS
182 if (IsCheckable())
183 XtAddCallback ((Widget) m_buttonWidget,
184 XmNvalueChangedCallback,
185 (XtCallbackProc) wxMenuItemCallback,
186 (XtPointer) this);
187 else
188 XtAddCallback ((Widget) m_buttonWidget,
189 XmNactivateCallback,
190 (XtCallbackProc) wxMenuItemCallback,
191 (XtPointer) this);
192 XtAddCallback ((Widget) m_buttonWidget,
193 XmNarmCallback,
194 (XtCallbackProc) wxMenuItemArmCallback,
195 (XtPointer) this);
196 XtAddCallback ((Widget) m_buttonWidget,
197 XmNdisarmCallback,
198 (XtCallbackProc) wxMenuItemDisarmCallback,
199 (XtPointer) this);
50414e24 200 }
2d120f83 201 else if (GetId() == -1)
50414e24 202 {
2d120f83
JS
203 m_buttonWidget = (WXWidget) XtVaCreateManagedWidget ("separator",
204 xmSeparatorGadgetClass, (Widget) menu, NULL);
50414e24 205 }
2d120f83 206 else if (m_pSubMenu)
50414e24 207 {
2d120f83
JS
208 m_buttonWidget = m_pSubMenu->CreateMenu (menuBar, menu, topMenu, m_strName, TRUE);
209 m_pSubMenu->SetButtonWidget(m_buttonWidget);
210 XtAddCallback ((Widget) m_buttonWidget,
211 XmNcascadingCallback,
212 (XtCallbackProc) wxMenuItemArmCallback,
213 (XtPointer) this);
50414e24 214 }
2d120f83
JS
215 if (m_buttonWidget)
216 XtSetSensitive ((Widget) m_buttonWidget, (Boolean) IsEnabled());
50414e24
JS
217}
218
219void wxMenuItem::DestroyItem(bool full)
220{
2d120f83 221 if (GetId() == -2)
50414e24 222 {
2d120f83 223 ; // Nothing
31528cd3 224
50414e24 225 }
2d120f83 226 else if ((!m_strName.IsNull() && (m_strName != "")) && !m_pSubMenu)
50414e24 227 {
2d120f83
JS
228 if (m_buttonWidget)
229 {
230 if (IsCheckable())
231 XtRemoveCallback ((Widget) m_buttonWidget, XmNvalueChangedCallback,
232 wxMenuItemCallback, (XtPointer) this);
233 else
234 XtRemoveCallback ((Widget) m_buttonWidget, XmNactivateCallback,
235 wxMenuItemCallback, (XtPointer) this);
236 XtRemoveCallback ((Widget) m_buttonWidget, XmNarmCallback,
237 wxMenuItemArmCallback, (XtPointer) this);
238 XtRemoveCallback ((Widget) m_buttonWidget, XmNdisarmCallback,
239 wxMenuItemDisarmCallback, (XtPointer) this);
240 }
50414e24 241 }
2d120f83 242 else if (GetId() == -1)
50414e24 243 {
2d120f83 244 ; // Nothing
31528cd3 245
50414e24 246 }
2d120f83 247 else if (GetSubMenu())
50414e24 248 {
2d120f83
JS
249 if (m_buttonWidget)
250 {
251 XtRemoveCallback ((Widget) m_buttonWidget, XmNcascadingCallback,
252 wxMenuItemArmCallback, (XtPointer) this);
253 }
254 m_pSubMenu->DestroyMenu(full);
255 if (full)
256 m_buttonWidget = NULL;
50414e24 257 }
31528cd3 258
2d120f83 259 if (m_buttonWidget && full)
50414e24 260 {
2d120f83
JS
261 XtDestroyWidget ((Widget) m_buttonWidget);
262 m_buttonWidget = (WXWidget) 0;
50414e24
JS
263 }
264}
265
266void wxMenuItem::SetLabel(const wxString& label)
267{
2d120f83 268 char mnem = wxFindMnemonic (label);
31528cd3
VZ
269 wxString label2 = wxStripMenuCodes(label);
270
2d120f83 271 m_strName = label;
31528cd3 272
2d120f83 273 if (m_buttonWidget)
50414e24 274 {
31528cd3 275 wxXmString label_str(label2);
2d120f83
JS
276 XtVaSetValues ((Widget) m_buttonWidget,
277 XmNlabelString, label_str,
278 NULL);
2d120f83
JS
279 if (mnem != 0)
280 XtVaSetValues ((Widget) m_buttonWidget, XmNmnemonic, mnem, NULL);
31528cd3 281 char *accel = wxFindAccelerator (label2);
2d120f83
JS
282 if (accel)
283 XtVaSetValues ((Widget) m_buttonWidget, XmNaccelerator, accel, NULL);
31528cd3
VZ
284
285 XmString accel_str = wxFindAcceleratorText (label2);
2d120f83 286 if (accel_str)
50414e24 287 {
2d120f83
JS
288 XtVaSetValues ((Widget) m_buttonWidget, XmNacceleratorText, accel_str, NULL);
289 XmStringFree (accel_str);
50414e24
JS
290 }
291 }
292}
293
294void wxMenuItemCallback (Widget w, XtPointer clientData,
2d120f83 295 XtPointer ptr)
50414e24 296{
2d120f83
JS
297 wxMenuItem *item = (wxMenuItem *) clientData;
298 if (item)
50414e24 299 {
2d120f83
JS
300 if (item->IsCheckable())
301 {
302 Boolean isChecked = FALSE;
303 XtVaGetValues ((Widget) item->GetButtonWidget(), XmNset, & isChecked, NULL);
304 item->SetChecked(isChecked);
305 }
306 if (item->GetMenuBar() && item->GetMenuBar()->GetMenuBarFrame())
307 {
308 wxCommandEvent commandEvent(wxEVT_COMMAND_MENU_SELECTED, item->GetId());
309 commandEvent.SetEventObject(item->GetMenuBar()->GetMenuBarFrame());
310 commandEvent.SetInt( item->GetId() );
31528cd3 311
2d120f83
JS
312 item->GetMenuBar()->GetMenuBarFrame()->GetEventHandler()->ProcessEvent(commandEvent);
313 }
314 else if (item->GetTopMenu())
315 {
316 wxCommandEvent event (wxEVT_COMMAND_MENU_SELECTED, item->GetId());
317 event.SetEventObject(item->GetTopMenu());
318 event.SetInt( item->GetId() );
31528cd3 319
2d120f83
JS
320 item->GetTopMenu()->ProcessCommand (event);
321 }
50414e24
JS
322 }
323}
324
2d120f83
JS
325void wxMenuItemArmCallback (Widget w, XtPointer clientData,
326 XtPointer ptr)
50414e24 327{
2d120f83
JS
328 wxMenuItem *item = (wxMenuItem *) clientData;
329 if (item)
50414e24 330 {
2d120f83
JS
331 if (item->GetMenuBar() && item->GetMenuBar()->GetMenuBarFrame())
332 {
333 wxMenuEvent menuEvent(wxEVT_MENU_HIGHLIGHT, item->GetId());
334 menuEvent.SetEventObject(item->GetMenuBar()->GetMenuBarFrame());
31528cd3 335
2d120f83
JS
336 item->GetMenuBar()->GetMenuBarFrame()->GetEventHandler()->ProcessEvent(menuEvent);
337 }
50414e24
JS
338 }
339}
340
31528cd3 341void
50414e24 342wxMenuItemDisarmCallback (Widget w, XtPointer clientData,
2d120f83 343 XtPointer ptr)
50414e24 344{
2d120f83
JS
345 wxMenuItem *item = (wxMenuItem *) clientData;
346 if (item)
50414e24 347 {
2d120f83
JS
348 if (item->GetMenuBar() && item->GetMenuBar()->GetMenuBarFrame())
349 {
350 // TODO: not sure this is correct, since -1 means something
351 // special to event system
352 wxMenuEvent menuEvent(wxEVT_MENU_HIGHLIGHT, -1);
353 menuEvent.SetEventObject(item->GetMenuBar()->GetMenuBarFrame());
31528cd3 354
2d120f83
JS
355 item->GetMenuBar()->GetMenuBarFrame()->GetEventHandler()->ProcessEvent(menuEvent);
356 }
50414e24
JS
357 }
358}
359