]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/os2/menuitem.cpp
added xpm
[wxWidgets.git] / src / os2 / menuitem.cpp
... / ...
CommitLineData
1///////////////////////////////////////////////////////////////////////////////
2// Name: menuitem.cpp
3// Purpose: wxMenuItem implementation
4// Author: David Webster
5// Modified by:
6// Created: 10/10/98
7// RCS-ID: $Id$
8// Copyright: (c) David Webster
9// Licence: wxWindows licence
10///////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// headers & declarations
14// ============================================================================
15
16#ifdef __GNUG__
17 #pragma implementation "menuitem.h"
18#endif
19
20// For compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
22
23#ifndef WX_PRECOMP
24 #include "wx/font.h"
25 #include "wx/bitmap.h"
26 #include "wx/settings.h"
27 #include "wx/font.h"
28 #include "wx/window.h"
29 #include "wx/accel.h"
30 #include "wx/menu.h"
31 #include "wx/string.h"
32#endif
33
34#include "wx/menuitem.h"
35#include "wx/log.h"
36
37#if wxUSE_ACCEL
38 #include "wx/accel.h"
39#endif // wxUSE_ACCEL
40
41#include "wx/os2/private.h"
42
43// ---------------------------------------------------------------------------
44// macro
45// ---------------------------------------------------------------------------
46
47// hide the ugly cast
48#define GetHMenuOf(menu) ((HMENU)menu->GetHMenu())
49
50// conditional compilation
51#if wxUSE_OWNER_DRAWN
52 #define OWNER_DRAWN_ONLY( code ) if ( IsOwnerDrawn() ) code
53#else // !wxUSE_OWNER_DRAWN
54 #define OWNER_DRAWN_ONLY( code )
55#endif // wxUSE_OWNER_DRAWN/!wxUSE_OWNER_DRAWN
56
57// ----------------------------------------------------------------------------
58// static function for translating menu labels
59// ----------------------------------------------------------------------------
60
61static wxString TextToLabel(const wxString& rTitle)
62{
63 wxString Title;
64 const wxChar *pc;
65 for (pc = rTitle; *pc != wxT('\0'); pc++ )
66 {
67 if (*pc == wxT('&') )
68 {
69 if (*(pc+1) == wxT('&'))
70 {
71 pc++;
72 Title << wxT('&');
73 }
74 else
75 Title << wxT('~');
76 }
77// else if (*pc == wxT('/'))
78// {
79// Title << wxT('\\');
80// }
81 else
82 {
83 if ( *pc == wxT('~') )
84 {
85 // tildes must be doubled to prevent them from being
86 // interpreted as accelerator character prefix by PM ???
87 Title << *pc;
88 }
89 Title << *pc;
90 }
91 }
92 return Title;
93}
94
95// ============================================================================
96// implementation
97// ============================================================================
98
99// ----------------------------------------------------------------------------
100// dynamic classes implementation
101// ----------------------------------------------------------------------------
102
103 #if wxUSE_OWNER_DRAWN
104 IMPLEMENT_DYNAMIC_CLASS2(wxMenuItem, wxMenuItemBase, wxOwnerDrawn)
105 #else //!USE_OWNER_DRAWN
106 IMPLEMENT_DYNAMIC_CLASS(wxMenuItem, wxMenuItemBase)
107 #endif //USE_OWNER_DRAWN
108
109// ----------------------------------------------------------------------------
110// wxMenuItem
111// ----------------------------------------------------------------------------
112
113// ctor & dtor
114// -----------
115
116wxMenuItem::wxMenuItem(
117 wxMenu* pParentMenu
118, int nId
119, const wxString& rText
120, const wxString& rStrHelp
121, bool bCheckable
122, wxMenu* pSubMenu
123)
124#if wxUSE_OWNER_DRAWN
125: wxOwnerDrawn( TextToLabel(rText)
126 ,bCheckable
127 )
128#endif // owner drawn
129{
130 wxASSERT_MSG(pParentMenu != NULL, wxT("a menu item should have a parent"));
131
132#if wxUSE_OWNER_DRAWN
133
134 //
135 // Set default menu colors
136 //
137 #define SYS_COLOR(c) (wxSystemSettings::GetSystemColour(wxSYS_COLOUR_##c))
138
139 SetTextColour(SYS_COLOR(MENUTEXT));
140 SetBackgroundColour(SYS_COLOR(MENU));
141
142 //
143 // We don't want normal items be owner-drawn
144 //
145 ResetOwnerDrawn();
146
147 #undef SYS_COLOR
148#endif // wxUSE_OWNER_DRAWN
149
150 m_parentMenu = pParentMenu;
151 m_subMenu = pSubMenu;
152 m_isEnabled = TRUE;
153 m_isChecked = FALSE;
154 m_id = nId;
155 m_text = TextToLabel(rText);
156 m_isCheckable = bCheckable;
157 m_help = rStrHelp;
158 memset(&m_vMenuData, '\0', sizeof(m_vMenuData));
159 m_vMenuData.id= nId;
160} // end of wxMenuItem::wxMenuItem
161
162wxMenuItem::~wxMenuItem()
163{
164} // end of wxMenuItem::~wxMenuItem
165
166//
167// Misc
168// ----
169
170//
171// Return the id for calling Win32 API functions
172//
173int wxMenuItem::GetRealId() const
174{
175 return m_subMenu ? (int)m_subMenu->GetHMenu() : GetId();
176} // end of wxMenuItem::GetRealId
177
178//
179// Get item state
180// --------------
181bool wxMenuItem::IsChecked() const
182{
183 USHORT uFlag = SHORT1FROMMR(::WinSendMsg( GetHMenuOf(m_parentMenu)
184 ,MM_QUERYITEMATTR
185 ,MPFROM2SHORT(GetId(), TRUE)
186 ,MPFROMSHORT(MIA_CHECKED)
187 ));
188
189 return (uFlag & MIA_CHECKED);
190} // end of wxMenuItem::IsChecked
191
192wxString wxMenuItemBase::GetLabelFromText(
193 const wxString& rText
194)
195{
196 wxString label;
197 for ( const wxChar *pc = rText.c_str(); *pc; pc++ )
198 {
199 if ( *pc == wxT('~') || *pc == wxT('&') )
200 {
201 // '~' is the escape character for GTK+ and '&' is the one for
202 // wxWindows - skip both of them
203 continue;
204 }
205
206 label += *pc;
207 }
208 return label;
209}
210
211// accelerators
212// ------------
213
214#if wxUSE_ACCEL
215
216wxAcceleratorEntry *wxMenuItem::GetAccel() const
217{
218 return wxGetAccelFromString(GetText());
219}
220
221#endif // wxUSE_ACCEL
222
223// change item state
224// -----------------
225
226void wxMenuItem::Enable(
227 bool bEnable
228)
229{
230 bool bOk;
231
232 if (m_isEnabled == bEnable)
233 return;
234 if (bEnable)
235 bOk = (bool)::WinSendMsg( GetHMenuOf(m_parentMenu)
236 ,MM_SETITEMATTR
237 ,MPFROM2SHORT(GetRealId(), TRUE)
238 ,MPFROM2SHORT(MIA_DISABLED, FALSE)
239 );
240 else
241 bOk = (bool)::WinSendMsg( GetHMenuOf(m_parentMenu)
242 ,MM_SETITEMATTR
243 ,MPFROM2SHORT(GetRealId(), TRUE)
244 ,MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED)
245 );
246 if (!bOk)
247 {
248 wxLogLastError("EnableMenuItem");
249 }
250 wxMenuItemBase::Enable(bEnable);
251} // end of wxMenuItem::Enable
252
253void wxMenuItem::Check(
254 bool bCheck
255)
256{
257 bool bOk;
258
259 wxCHECK_RET( m_isCheckable, wxT("only checkable items may be checked") );
260 if (m_isChecked == bCheck)
261 return;
262 if (bCheck)
263 bOk = (bool)::WinSendMsg( GetHMenuOf(m_parentMenu)
264 ,MM_SETITEMATTR
265 ,MPFROM2SHORT(GetRealId(), TRUE)
266 ,MPFROM2SHORT(MIA_CHECKED, MIA_CHECKED)
267 );
268 else
269 bOk = (bool)::WinSendMsg( GetHMenuOf(m_parentMenu)
270 ,MM_SETITEMATTR
271 ,MPFROM2SHORT(GetRealId(), TRUE)
272 ,MPFROM2SHORT(MIA_CHECKED, FALSE)
273 );
274 if (!bOk)
275 {
276 wxLogLastError("CheckMenuItem");
277 }
278 wxMenuItemBase::Check(bCheck);
279} // end of wxMenuItem::Check
280
281void wxMenuItem::SetText(
282 const wxString& rText
283)
284{
285 //
286 // Don't do anything if label didn't change
287 //
288
289 wxString Text = TextToLabel(rText);
290 if (m_text == Text)
291 return;
292
293 wxMenuItemBase::SetText(Text);
294 OWNER_DRAWN_ONLY(wxOwnerDrawn::SetName(Text));
295
296 HWND hMenu = GetHMenuOf(m_parentMenu);
297
298 wxCHECK_RET(hMenu, wxT("menuitem without menu"));
299
300#if wxUSE_ACCEL
301 m_parentMenu->UpdateAccel(this);
302#endif // wxUSE_ACCEL
303
304 USHORT uId = GetRealId();
305 MENUITEM vItem;
306 USHORT uFlagsOld;
307
308 if (!::WinSendMsg( hMenu
309 ,MM_QUERYITEM
310 ,MPFROM2SHORT(uId, TRUE)
311 ,(MPARAM)&vItem
312 ))
313 {
314 wxLogLastError("GetMenuState");
315 }
316 else
317 {
318 uFlagsOld = vItem.afStyle;
319 if (IsSubMenu())
320 {
321 uFlagsOld |= MIS_SUBMENU;
322 }
323
324 BYTE* pData;
325
326#if wxUSE_OWNER_DRAWN
327 if (IsOwnerDrawn())
328 {
329 uFlagsOld |= MIS_OWNERDRAW;
330 pData = (BYTE*)this;
331 }
332 else
333#endif //owner drawn
334 {
335 uFlagsOld |= MIS_TEXT;
336 pData = (BYTE*)Text.c_str();
337 }
338
339 //
340 // Set the style
341 //
342 if (!::WinSendMsg( hMenu
343 ,MM_SETITEM
344 ,MPFROM2SHORT(uId, TRUE)
345 ,(MPARAM)&vItem
346 ))
347 {
348 wxLogLastError(wxT("ModifyMenu"));
349 }
350
351 //
352 // Set the text
353 //
354 if (::WinSendMsg( hMenu
355 ,MM_SETITEMTEXT
356 ,MPFROMSHORT(uId)
357 ,(MPARAM)pData
358 ))
359 {
360 wxLogLastError(wxT("ModifyMenu"));
361 }
362 }
363} // end of wxMenuItem::SetText
364
365void wxMenuItem::SetCheckable(
366 bool bCheckable
367)
368{
369 wxMenuItemBase::SetCheckable(bCheckable);
370 OWNER_DRAWN_ONLY(wxOwnerDrawn::SetCheckable(bCheckable));
371} // end of wxMenuItem::SetCheckable
372
373// ----------------------------------------------------------------------------
374// wxMenuItemBase
375// ----------------------------------------------------------------------------
376
377wxMenuItem* wxMenuItemBase::New(
378 wxMenu* pParentMenu
379, int nId
380, const wxString& rName
381, const wxString& rHelp
382, bool bIsCheckable
383, wxMenu* pSubMenu
384)
385{
386 return new wxMenuItem( pParentMenu
387 ,nId
388 ,rName
389 ,rHelp
390 ,bIsCheckable
391 ,pSubMenu
392 );
393} // end of wxMenuItemBase::New
394