]> git.saurik.com Git - wxWidgets.git/blame - src/motif/menuitem.cpp
added an error message if a bitmap can't be addedto the image list
[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;
b412f9be 73 m_bChecked = FALSE;
50414e24
JS
74
75 //// Motif-specific
76 m_menuBar = NULL;
77 m_buttonWidget = (WXWidget) NULL;
78 m_topMenu = NULL;
4bb6408c
JS
79}
80
81wxMenuItem::~wxMenuItem()
82{
83}
84
85// misc
86// ----
87
88// delete the sub menu
89void wxMenuItem::DeleteSubMenu()
90{
91 wxASSERT( m_pSubMenu != NULL );
92
93 delete m_pSubMenu;
94 m_pSubMenu = NULL;
95}
96
97// change item state
98// -----------------
99
100void wxMenuItem::Enable(bool bDoEnable)
101{
50414e24
JS
102 if ( m_bEnabled != bDoEnable )
103 {
104 if ( m_pSubMenu == NULL )
105 { // normal menu item
106 if (m_buttonWidget)
107 XtSetSensitive( (Widget) m_buttonWidget, (Boolean) bDoEnable);
4bb6408c
JS
108 }
109 else // submenu
110 {
50414e24
JS
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);
4bb6408c
JS
115 }
116
117 m_bEnabled = bDoEnable;
118 }
119}
120
121void wxMenuItem::Check(bool bDoCheck)
122{
123 wxCHECK_RET( IsCheckable(), "only checkable items may be checked" );
124
50414e24
JS
125 if ( m_bChecked != bDoCheck )
126 {
127 if (m_buttonWidget && XtIsSubclass ((Widget) m_buttonWidget, xmToggleButtonGadgetClass))
128 {
129 XtVaSetValues ( (Widget) m_buttonWidget, XmNset, (Boolean) bDoCheck, NULL);
130 }
4bb6408c
JS
131 m_bChecked = bDoCheck;
132 }
50414e24
JS
133}
134
135//// Motif-specific
136
137void wxMenuItem::CreateItem (WXWidget menu, wxMenuBar * menuBar, wxMenu * topMenu)
138{
139 m_menuBar = menuBar;
140 m_topMenu = topMenu;
141
142 if (GetId() == -2)
143 {
144 // Id=-2 identifies a Title item.
145 wxStripMenuCodes ((char*) (const char*) m_strName, wxBuffer);
146 m_buttonWidget = (WXWidget) XtVaCreateManagedWidget (wxBuffer,
147 xmLabelGadgetClass, (Widget) menu, NULL);
148 }
149 else if ((!m_strName.IsNull() && m_strName != "") && (!m_pSubMenu))
150 {
151 wxStripMenuCodes ((char*) (const char*) m_strName, wxBuffer);
152 if (IsCheckable())
153 {
154 m_buttonWidget = (WXWidget) XtVaCreateManagedWidget (wxBuffer,
155 xmToggleButtonGadgetClass, (Widget) menu,
156 NULL);
157 XtVaSetValues ((Widget) m_buttonWidget, XmNset, (Boolean) IsChecked(), NULL);
158 }
159 else
160 m_buttonWidget = (WXWidget) XtVaCreateManagedWidget (wxBuffer,
161 xmPushButtonGadgetClass, (Widget) menu,
162 NULL);
163 char mnem = wxFindMnemonic (m_strName);
164 if (mnem != 0)
165 XtVaSetValues ((Widget) m_buttonWidget, XmNmnemonic, mnem, NULL);
166
167 //// TODO: proper accelerator treatment. What does wxFindAccelerator
168 //// look for?
169 strcpy(wxBuffer, (char*) (const char*) m_strName);
170 char *accel = wxFindAccelerator (wxBuffer);
171 if (accel)
172 XtVaSetValues ((Widget) m_buttonWidget, XmNaccelerator, accel, NULL);
173
174 // TODO: What does this do?
175 strcpy(wxBuffer, (char*) (const char*) m_strName);
176 XmString accel_str = wxFindAcceleratorText (wxBuffer);
177 if (accel_str)
178 {
179 XtVaSetValues ((Widget) m_buttonWidget, XmNacceleratorText, accel_str, NULL);
180 XmStringFree (accel_str);
181 }
182
183 if (IsCheckable())
184 XtAddCallback ((Widget) m_buttonWidget,
185 XmNvalueChangedCallback,
186 (XtCallbackProc) wxMenuItemCallback,
187 (XtPointer) this);
188 else
189 XtAddCallback ((Widget) m_buttonWidget,
190 XmNactivateCallback,
191 (XtCallbackProc) wxMenuItemCallback,
192 (XtPointer) this);
193 XtAddCallback ((Widget) m_buttonWidget,
194 XmNarmCallback,
195 (XtCallbackProc) wxMenuItemArmCallback,
196 (XtPointer) this);
197 XtAddCallback ((Widget) m_buttonWidget,
198 XmNdisarmCallback,
199 (XtCallbackProc) wxMenuItemDisarmCallback,
200 (XtPointer) this);
201 }
202 else if (GetId() == -1)
203 {
204 m_buttonWidget = (WXWidget) XtVaCreateManagedWidget ("separator",
205 xmSeparatorGadgetClass, (Widget) menu, NULL);
206 }
207 else if (m_pSubMenu)
208 {
209 m_buttonWidget = m_pSubMenu->CreateMenu (menuBar, menu, topMenu, m_strName, TRUE);
210 m_pSubMenu->SetButtonWidget(m_buttonWidget);
211 XtAddCallback ((Widget) m_buttonWidget,
212 XmNcascadingCallback,
213 (XtCallbackProc) wxMenuItemArmCallback,
214 (XtPointer) this);
215 }
216 if (m_buttonWidget)
217 XtSetSensitive ((Widget) m_buttonWidget, (Boolean) IsEnabled());
218}
219
220void wxMenuItem::DestroyItem(bool full)
221{
222 if (GetId() == -2)
223 {
224 ; // Nothing
225
226 }
227 else if ((!m_strName.IsNull() && (m_strName != "")) && !m_pSubMenu)
228 {
229 if (m_buttonWidget)
230 {
231 if (IsCheckable())
232 XtRemoveCallback ((Widget) m_buttonWidget, XmNvalueChangedCallback,
233 wxMenuItemCallback, (XtPointer) this);
234 else
235 XtRemoveCallback ((Widget) m_buttonWidget, XmNactivateCallback,
236 wxMenuItemCallback, (XtPointer) this);
237 XtRemoveCallback ((Widget) m_buttonWidget, XmNarmCallback,
238 wxMenuItemArmCallback, (XtPointer) this);
239 XtRemoveCallback ((Widget) m_buttonWidget, XmNdisarmCallback,
240 wxMenuItemDisarmCallback, (XtPointer) this);
241 }
242 }
243 else if (GetId() == -1)
244 {
245 ; // Nothing
246
247 }
248 else if (GetSubMenu())
249 {
250 if (m_buttonWidget)
251 {
252 XtRemoveCallback ((Widget) m_buttonWidget, XmNcascadingCallback,
253 wxMenuItemArmCallback, (XtPointer) this);
254 }
255 m_pSubMenu->DestroyMenu(full);
256 if (full)
257 m_buttonWidget = NULL;
258 }
259
260 if (m_buttonWidget && full)
261 {
262 XtDestroyWidget ((Widget) m_buttonWidget);
263 m_buttonWidget = (WXWidget) 0;
264 }
265}
266
267void wxMenuItem::SetLabel(const wxString& label)
268{
269 char mnem = wxFindMnemonic (label);
270 wxStripMenuCodes ((char*) (const char*) label, wxBuffer);
271
272 m_strName = label;
273
274 if (m_buttonWidget)
275 {
276 XmString label_str = XmStringCreateSimple (wxBuffer);
277 XtVaSetValues ((Widget) m_buttonWidget,
278 XmNlabelString, label_str,
279 NULL);
280 XmStringFree (label_str);
281 if (mnem != 0)
282 XtVaSetValues ((Widget) m_buttonWidget, XmNmnemonic, mnem, NULL);
283 strcpy(wxBuffer, (char*) (const char*) label);
284 char *accel = wxFindAccelerator (wxBuffer);
285 if (accel)
286 XtVaSetValues ((Widget) m_buttonWidget, XmNaccelerator, accel, NULL);
287
288 strcpy(wxBuffer, (char*) (const char*) label);
289 XmString accel_str = wxFindAcceleratorText (wxBuffer);
290 if (accel_str)
291 {
292 XtVaSetValues ((Widget) m_buttonWidget, XmNacceleratorText, accel_str, NULL);
293 XmStringFree (accel_str);
294 }
295 }
296}
297
298void wxMenuItemCallback (Widget w, XtPointer clientData,
299 XtPointer ptr)
300{
301 wxMenuItem *item = (wxMenuItem *) clientData;
302 if (item)
303 {
304 if (item->IsCheckable())
305 {
306 Boolean isChecked = FALSE;
307 XtVaGetValues ((Widget) item->GetButtonWidget(), XmNset, & isChecked, NULL);
308 item->SetChecked(isChecked);
309 }
310 if (item->GetMenuBar() && item->GetMenuBar()->GetMenuBarFrame())
311 {
312 wxCommandEvent commandEvent(wxEVT_COMMAND_MENU_SELECTED, item->GetId());
313 commandEvent.SetEventObject(item->GetMenuBar()->GetMenuBarFrame());
b412f9be 314 commandEvent.SetInt( item->GetId() );
50414e24
JS
315
316 item->GetMenuBar()->GetMenuBarFrame()->GetEventHandler()->ProcessEvent(commandEvent);
317 }
318 else if (item->GetTopMenu())
319 {
320 wxCommandEvent event (wxEVT_COMMAND_MENU_SELECTED, item->GetId());
321 event.SetEventObject(item->GetTopMenu());
b412f9be
JS
322 event.SetInt( item->GetId() );
323
50414e24
JS
324 item->GetTopMenu()->ProcessCommand (event);
325 }
326 }
327}
328
329void
330wxMenuItemArmCallback (Widget w, XtPointer clientData,
331 XtPointer ptr)
332{
333 wxMenuItem *item = (wxMenuItem *) clientData;
334 if (item)
335 {
336 if (item->GetMenuBar() && item->GetMenuBar()->GetMenuBarFrame())
337 {
338 wxMenuEvent menuEvent(wxEVT_MENU_HIGHLIGHT, item->GetId());
339 menuEvent.SetEventObject(item->GetMenuBar()->GetMenuBarFrame());
340
341 item->GetMenuBar()->GetMenuBarFrame()->GetEventHandler()->ProcessEvent(menuEvent);
342 }
343 }
344}
345
346void
347wxMenuItemDisarmCallback (Widget w, XtPointer clientData,
348 XtPointer ptr)
349{
350 wxMenuItem *item = (wxMenuItem *) clientData;
351 if (item)
352 {
353 if (item->GetMenuBar() && item->GetMenuBar()->GetMenuBarFrame())
354 {
355 // TODO: not sure this is correct, since -1 means something
356 // special to event system
357 wxMenuEvent menuEvent(wxEVT_MENU_HIGHLIGHT, -1);
358 menuEvent.SetEventObject(item->GetMenuBar()->GetMenuBarFrame());
359
360 item->GetMenuBar()->GetMenuBarFrame()->GetEventHandler()->ProcessEvent(menuEvent);
361 }
362 }
363}
364