]> git.saurik.com Git - wxWidgets.git/blame - src/motif/menuitem.cpp
More Motif additions: mdi and sashtest samples now just about work!
[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,
34 XtPointer ptr);
35void wxMenuItemArmCallback (Widget w, XtPointer clientData,
36 XtPointer ptr);
37void wxMenuItemDisarmCallback (Widget w, XtPointer clientData,
38 XtPointer ptr);
4bb6408c
JS
39
40// ============================================================================
41// implementation
42// ============================================================================
43
44// ----------------------------------------------------------------------------
45// dynamic classes implementation
46// ----------------------------------------------------------------------------
47
48#if !USE_SHARED_LIBRARY
49 IMPLEMENT_DYNAMIC_CLASS(wxMenuItem, wxObject)
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) :
50414e24 63 m_strHelp(strHelp),
4bb6408c 64 m_bCheckable(bCheckable),
50414e24 65 m_strName(strName)
4bb6408c
JS
66{
67 wxASSERT( pParentMenu != NULL );
68
69 m_pParentMenu = pParentMenu;
70 m_pSubMenu = pSubMenu;
71 m_idItem = id;
72 m_bEnabled = TRUE;
50414e24
JS
73
74 //// Motif-specific
75 m_menuBar = NULL;
76 m_buttonWidget = (WXWidget) NULL;
77 m_topMenu = NULL;
4bb6408c
JS
78}
79
80wxMenuItem::~wxMenuItem()
81{
82}
83
84// misc
85// ----
86
87// delete the sub menu
88void wxMenuItem::DeleteSubMenu()
89{
90 wxASSERT( m_pSubMenu != NULL );
91
92 delete m_pSubMenu;
93 m_pSubMenu = NULL;
94}
95
96// change item state
97// -----------------
98
99void wxMenuItem::Enable(bool bDoEnable)
100{
50414e24
JS
101 if ( m_bEnabled != bDoEnable )
102 {
103 if ( m_pSubMenu == NULL )
104 { // normal menu item
105 if (m_buttonWidget)
106 XtSetSensitive( (Widget) m_buttonWidget, (Boolean) bDoEnable);
4bb6408c
JS
107 }
108 else // submenu
109 {
50414e24
JS
110 // Maybe we should apply this to all items in the submenu?
111 // Or perhaps it works anyway.
112 if (m_buttonWidget)
113 XtSetSensitive( (Widget) m_buttonWidget, (Boolean) bDoEnable);
4bb6408c
JS
114 }
115
116 m_bEnabled = bDoEnable;
117 }
118}
119
120void wxMenuItem::Check(bool bDoCheck)
121{
122 wxCHECK_RET( IsCheckable(), "only checkable items may be checked" );
123
50414e24
JS
124 if ( m_bChecked != bDoCheck )
125 {
126 if (m_buttonWidget && XtIsSubclass ((Widget) m_buttonWidget, xmToggleButtonGadgetClass))
127 {
128 XtVaSetValues ( (Widget) m_buttonWidget, XmNset, (Boolean) bDoCheck, NULL);
129 }
4bb6408c
JS
130 m_bChecked = bDoCheck;
131 }
50414e24
JS
132}
133
134//// Motif-specific
135
136void wxMenuItem::CreateItem (WXWidget menu, wxMenuBar * menuBar, wxMenu * topMenu)
137{
138 m_menuBar = menuBar;
139 m_topMenu = topMenu;
140
141 if (GetId() == -2)
142 {
143 // Id=-2 identifies a Title item.
144 wxStripMenuCodes ((char*) (const char*) m_strName, wxBuffer);
145 m_buttonWidget = (WXWidget) XtVaCreateManagedWidget (wxBuffer,
146 xmLabelGadgetClass, (Widget) menu, NULL);
147 }
148 else if ((!m_strName.IsNull() && m_strName != "") && (!m_pSubMenu))
149 {
150 wxStripMenuCodes ((char*) (const char*) m_strName, wxBuffer);
151 if (IsCheckable())
152 {
153 m_buttonWidget = (WXWidget) XtVaCreateManagedWidget (wxBuffer,
154 xmToggleButtonGadgetClass, (Widget) menu,
155 NULL);
156 XtVaSetValues ((Widget) m_buttonWidget, XmNset, (Boolean) IsChecked(), NULL);
157 }
158 else
159 m_buttonWidget = (WXWidget) XtVaCreateManagedWidget (wxBuffer,
160 xmPushButtonGadgetClass, (Widget) menu,
161 NULL);
162 char mnem = wxFindMnemonic (m_strName);
163 if (mnem != 0)
164 XtVaSetValues ((Widget) m_buttonWidget, XmNmnemonic, mnem, NULL);
165
166 //// TODO: proper accelerator treatment. What does wxFindAccelerator
167 //// look for?
168 strcpy(wxBuffer, (char*) (const char*) m_strName);
169 char *accel = wxFindAccelerator (wxBuffer);
170 if (accel)
171 XtVaSetValues ((Widget) m_buttonWidget, XmNaccelerator, accel, NULL);
172
173 // TODO: What does this do?
174 strcpy(wxBuffer, (char*) (const char*) m_strName);
175 XmString accel_str = wxFindAcceleratorText (wxBuffer);
176 if (accel_str)
177 {
178 XtVaSetValues ((Widget) m_buttonWidget, XmNacceleratorText, accel_str, NULL);
179 XmStringFree (accel_str);
180 }
181
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);
200 }
201 else if (GetId() == -1)
202 {
203 m_buttonWidget = (WXWidget) XtVaCreateManagedWidget ("separator",
204 xmSeparatorGadgetClass, (Widget) menu, NULL);
205 }
206 else if (m_pSubMenu)
207 {
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);
214 }
215 if (m_buttonWidget)
216 XtSetSensitive ((Widget) m_buttonWidget, (Boolean) IsEnabled());
217}
218
219void wxMenuItem::DestroyItem(bool full)
220{
221 if (GetId() == -2)
222 {
223 ; // Nothing
224
225 }
226 else if ((!m_strName.IsNull() && (m_strName != "")) && !m_pSubMenu)
227 {
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 }
241 }
242 else if (GetId() == -1)
243 {
244 ; // Nothing
245
246 }
247 else if (GetSubMenu())
248 {
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;
257 }
258
259 if (m_buttonWidget && full)
260 {
261 XtDestroyWidget ((Widget) m_buttonWidget);
262 m_buttonWidget = (WXWidget) 0;
263 }
264}
265
266void wxMenuItem::SetLabel(const wxString& label)
267{
268 char mnem = wxFindMnemonic (label);
269 wxStripMenuCodes ((char*) (const char*) label, wxBuffer);
270
271 m_strName = label;
272
273 if (m_buttonWidget)
274 {
275 XmString label_str = XmStringCreateSimple (wxBuffer);
276 XtVaSetValues ((Widget) m_buttonWidget,
277 XmNlabelString, label_str,
278 NULL);
279 XmStringFree (label_str);
280 if (mnem != 0)
281 XtVaSetValues ((Widget) m_buttonWidget, XmNmnemonic, mnem, NULL);
282 strcpy(wxBuffer, (char*) (const char*) label);
283 char *accel = wxFindAccelerator (wxBuffer);
284 if (accel)
285 XtVaSetValues ((Widget) m_buttonWidget, XmNaccelerator, accel, NULL);
286
287 strcpy(wxBuffer, (char*) (const char*) label);
288 XmString accel_str = wxFindAcceleratorText (wxBuffer);
289 if (accel_str)
290 {
291 XtVaSetValues ((Widget) m_buttonWidget, XmNacceleratorText, accel_str, NULL);
292 XmStringFree (accel_str);
293 }
294 }
295}
296
297void wxMenuItemCallback (Widget w, XtPointer clientData,
298 XtPointer ptr)
299{
300 wxMenuItem *item = (wxMenuItem *) clientData;
301 if (item)
302 {
303 if (item->IsCheckable())
304 {
305 Boolean isChecked = FALSE;
306 XtVaGetValues ((Widget) item->GetButtonWidget(), XmNset, & isChecked, NULL);
307 item->SetChecked(isChecked);
308 }
309 if (item->GetMenuBar() && item->GetMenuBar()->GetMenuBarFrame())
310 {
311 wxCommandEvent commandEvent(wxEVT_COMMAND_MENU_SELECTED, item->GetId());
312 commandEvent.SetEventObject(item->GetMenuBar()->GetMenuBarFrame());
313
314 item->GetMenuBar()->GetMenuBarFrame()->GetEventHandler()->ProcessEvent(commandEvent);
315 }
316 else if (item->GetTopMenu())
317 {
318 wxCommandEvent event (wxEVT_COMMAND_MENU_SELECTED, item->GetId());
319 event.SetEventObject(item->GetTopMenu());
320 item->GetTopMenu()->ProcessCommand (event);
321 }
322 }
323}
324
325void
326wxMenuItemArmCallback (Widget w, XtPointer clientData,
327 XtPointer ptr)
328{
329 wxMenuItem *item = (wxMenuItem *) clientData;
330 if (item)
331 {
332 if (item->GetMenuBar() && item->GetMenuBar()->GetMenuBarFrame())
333 {
334 wxMenuEvent menuEvent(wxEVT_MENU_HIGHLIGHT, item->GetId());
335 menuEvent.SetEventObject(item->GetMenuBar()->GetMenuBarFrame());
336
337 item->GetMenuBar()->GetMenuBarFrame()->GetEventHandler()->ProcessEvent(menuEvent);
338 }
339 }
340}
341
342void
343wxMenuItemDisarmCallback (Widget w, XtPointer clientData,
344 XtPointer ptr)
345{
346 wxMenuItem *item = (wxMenuItem *) clientData;
347 if (item)
348 {
349 if (item->GetMenuBar() && item->GetMenuBar()->GetMenuBarFrame())
350 {
351 // TODO: not sure this is correct, since -1 means something
352 // special to event system
353 wxMenuEvent menuEvent(wxEVT_MENU_HIGHLIGHT, -1);
354 menuEvent.SetEventObject(item->GetMenuBar()->GetMenuBarFrame());
355
356 item->GetMenuBar()->GetMenuBarFrame()->GetEventHandler()->ProcessEvent(menuEvent);
357 }
358 }
359}
360