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