]> git.saurik.com Git - wxWidgets.git/blame - src/os2/radiobut.cpp
adapting ownership semantics to cocoa convention
[wxWidgets.git] / src / os2 / radiobut.cpp
CommitLineData
0e320a79 1/////////////////////////////////////////////////////////////////////////////
521bf4ff 2// Name: src/os2/radiobut.cpp
0e320a79 3// Purpose: wxRadioButton
cdf1e714 4// Author: David Webster
0e320a79 5// Modified by:
cdf1e714 6// Created: 10/12/99
0e320a79 7// RCS-ID: $Id$
cdf1e714 8// Copyright: (c) David Webster
65571936 9// Licence: wxWindows licence
0e320a79
DW
10/////////////////////////////////////////////////////////////////////////////
11
cdf1e714
DW
12// For compilers that support precompilation, includes "wx.h".
13#include "wx/wxprec.h"
14
15#ifdef __BORLANDC__
b0b5881a 16 #pragma hdrstop
0e320a79
DW
17#endif
18
b0b5881a
WS
19#include "wx/radiobut.h"
20
cdf1e714 21#ifndef WX_PRECOMP
521bf4ff 22 #include <stdio.h>
521bf4ff
WS
23 #include "wx/brush.h"
24 #include "wx/dcscreen.h"
25 #include "wx/settings.h"
cdf1e714
DW
26#endif
27
11e59d47 28#include "wx/os2/private.h"
0e320a79 29
f289196b
DW
30extern void wxAssociateWinWithHandle( HWND hWnd
31 ,wxWindowOS2* pWin
32 );
33
1b086de1
DW
34void wxRadioButton::Init()
35{
b0b5881a 36 m_bFocusJustSet = false;
1b086de1
DW
37} // end of wxRadioButton::Init
38
b0b5881a 39void wxRadioButton::Command ( wxCommandEvent& rEvent )
cdf1e714 40{
3c299c3a
DW
41 SetValue ((rEvent.GetInt() != 0) );
42 ProcessCommand (rEvent);
43} // end of wxRadioButton::Command
44
b0b5881a
WS
45bool wxRadioButton::Create( wxWindow* pParent,
46 wxWindowID vId,
47 const wxString& rsLabel,
48 const wxPoint& rPos,
49 const wxSize& rSize,
50 long lStyle,
51 const wxValidator& rValidator,
52 const wxString& rsName )
0e320a79 53{
1b086de1
DW
54 if ( !CreateControl( pParent
55 ,vId
56 ,rPos
57 ,rSize
58 ,lStyle
1b086de1 59 ,rValidator
1b086de1 60 ,rsName))
b0b5881a 61 return false;
0e320a79 62
2b5f62a0 63 long lSstyle = WS_TABSTOP;
0e320a79 64
2b5f62a0
VZ
65 if (HasFlag(wxRB_GROUP))
66 lSstyle |= WS_GROUP;
67
68 //
69 // wxRB_SINGLE is a temporary workaround for the following problem: if you
70 // have 2 radiobuttons in the same group but which are not consecutive in
71 // the dialog, Windows can enter an infinite loop! The simplest way to
72 // reproduce it is to create radio button, then a panel and then another
73 // radio button: then checking the last button hangs the app.
74 //
75 // Ideally, we'd detect (and avoid) such situation automatically but for
76 // now, as I don't know how to do it, just allow the user to create
77 // BS_RADIOBUTTON buttons for such situations.
78 //
79 lSstyle |= HasFlag(wxRB_SINGLE) ? BS_RADIOBUTTON : BS_AUTORADIOBUTTON;
cdf1e714 80
1b086de1
DW
81 if (HasFlag(wxCLIP_SIBLINGS))
82 lSstyle |= WS_CLIPSIBLINGS;
83
9a83f860 84 if (!OS2CreateControl( wxT("BUTTON")
1b086de1
DW
85 ,lSstyle
86 ,rPos
87 ,rSize
88 ,rsLabel
89 ,0
90 ))
b0b5881a 91 return false;
cdf1e714 92
f289196b 93 wxAssociateWinWithHandle(m_hWnd, this);
1b086de1 94 if (HasFlag(wxRB_GROUP))
b0b5881a 95 SetValue(true);
0e320a79 96
f289196b 97 SetFont(*wxSMALL_FONT);
b0b5881a
WS
98 SetSize( rPos.x, rPos.y, rSize.x, rSize.y );
99 return true;
1b086de1 100} // end of wxRadioButton::Create
0e320a79 101
1b086de1
DW
102wxSize wxRadioButton::DoGetBestSize() const
103{
c5f975dd
SN
104 // We should probably compute snRadioSize but it seems to be a constant
105 // independent of its label's font size and not made available by OS/2.
106 static int snRadioSize = RADIO_SIZE;
cdf1e714 107
c5f975dd 108 wxString sStr = wxGetWindowText(GetHwnd());
1b086de1
DW
109 int nRadioWidth;
110 int nRadioHeight;
111
112 if (!sStr.empty())
cdf1e714 113 {
1b086de1
DW
114 GetTextExtent( sStr
115 ,&nRadioWidth
116 ,&nRadioHeight
3c299c3a 117 );
c5f975dd 118 nRadioWidth += snRadioSize;
1b086de1
DW
119 if (nRadioHeight < snRadioSize)
120 nRadioHeight = snRadioSize;
3c299c3a
DW
121 }
122 else
123 {
1b086de1
DW
124 nRadioWidth = snRadioSize;
125 nRadioHeight = snRadioSize;
cdf1e714 126 }
1b086de1
DW
127 return wxSize( nRadioWidth
128 ,nRadioHeight
129 );
130} // end of wxRadioButton::DoGetBestSize
0e320a79 131
3c299c3a 132//
0e320a79 133// Get single selection, for single choice list items
3c299c3a 134//
0e320a79
DW
135bool wxRadioButton::GetValue() const
136{
3c299c3a
DW
137 return((::WinSendMsg((HWND) GetHWND(), BM_QUERYCHECK, (MPARAM)0L, (MPARAM)0L) != 0));
138} // end of wxRadioButton::GetValue
0e320a79 139
6670f564 140bool wxRadioButton::OS2Command( WXUINT wParam, WXWORD WXUNUSED(wId) )
cdf1e714 141{
2b5f62a0 142 if (wParam != BN_CLICKED)
6670f564 143 return false;
2b5f62a0
VZ
144
145 if (m_bFocusJustSet)
146 {
147 //
148 // See above: we want to ignore this event
149 //
6670f564 150 m_bFocusJustSet = false;
2b5f62a0
VZ
151 }
152 else
3c299c3a 153 {
6670f564 154 bool bIsChecked = GetValue();
2b5f62a0
VZ
155
156 if (HasFlag(wxRB_SINGLE))
157 {
158 //
159 // When we use a "manual" radio button, we have to check the button
160 // ourselves -- but it's reset to unchecked state by the user code
161 // (presumably when another button is pressed)
162 //
163 if (!bIsChecked )
b0b5881a 164 SetValue(true);
2b5f62a0 165 }
6670f564 166 wxCommandEvent rEvent( wxEVT_COMMAND_RADIOBUTTON_SELECTED, m_windowId );
3c299c3a
DW
167 rEvent.SetEventObject(this);
168 ProcessCommand(rEvent);
3c299c3a 169 }
6670f564 170 return true;
3c299c3a 171} // end of wxRadioButton::OS2Command
cdf1e714 172
1b086de1
DW
173void wxRadioButton::SetFocus()
174{
175 // when the radio button receives a WM_SETFOCUS message it generates a
176 // BN_CLICKED which is totally unexpected and leads to catastrophic results
177 // if you pop up a dialog from the radio button event handler as, when the
178 // dialog is dismissed, the focus is returned to the radio button which
179 // generates BN_CLICKED which leads to showing another dialog and so on
180 // without end!
181 //
e94d504d 182 // to avoid this, we drop the pseudo BN_CLICKED events generated when the
1b086de1 183 // button gains focus
6670f564 184 m_bFocusJustSet = true;
1b086de1
DW
185
186 wxControl::SetFocus();
187}
188
b0b5881a 189void wxRadioButton::SetLabel( const wxString& rsLabel )
cdf1e714 190{
e94d504d
SN
191 wxString sLabel = ::wxPMTextToLabel(rsLabel);
192 ::WinSetWindowText((HWND)GetHWND(), (const char *)sLabel.c_str());
3c299c3a 193} // end of wxRadioButton::SetLabel
cdf1e714 194
b0b5881a 195void wxRadioButton::SetValue( bool bValue )
cdf1e714 196{
3c299c3a 197 ::WinSendMsg((HWND)GetHWND(), BM_SETCHECK, (MPARAM)bValue, (MPARAM)0);
2b5f62a0
VZ
198 if (bValue)
199 {
200 const wxWindowList& rSiblings = GetParent()->GetChildren();
2461cfa0 201 wxWindowList::compatibility_iterator nodeThis = rSiblings.Find(this);
2b5f62a0 202
9a83f860 203 wxCHECK_RET(nodeThis, wxT("radio button not a child of its parent?"));
2b5f62a0 204
2b5f62a0 205 //
6e348b12
DW
206 // If it's not the first item of the group ...
207 //
208 if ( !HasFlag(wxRB_GROUP) )
2b5f62a0 209 {
6e348b12
DW
210 //
211 // ...turn off all radio buttons before this one
212 //
2461cfa0
SN
213 for ( wxWindowList::compatibility_iterator nodeBefore = nodeThis->GetPrevious();
214 nodeBefore;
215 nodeBefore = nodeBefore->GetPrevious() )
6e348b12 216 {
2461cfa0 217 wxRadioButton* pBtn = wxDynamicCast( nodeBefore->GetData()
2b5f62a0
VZ
218 ,wxRadioButton
219 );
6e348b12
DW
220 if (!pBtn)
221 {
222 //
223 // The radio buttons in a group must be consecutive, so there
224 // are no more of them
225 //
226 break;
227 }
b0b5881a 228 pBtn->SetValue(false);
6e348b12
DW
229 if (pBtn->HasFlag(wxRB_GROUP))
230 {
231 //
232 // Even if there are other radio buttons before this one,
233 // they're not in the same group with us
234 //
235 break;
236 }
2b5f62a0
VZ
237 }
238 }
239
6e348b12 240 //
2b5f62a0
VZ
241 // ... and all after this one
242 //
2461cfa0
SN
243 for (wxWindowList::compatibility_iterator nodeAfter = nodeThis->GetNext();
244 nodeAfter;
245 nodeAfter = nodeAfter->GetNext())
2b5f62a0 246 {
2461cfa0 247 wxRadioButton* pBtn = wxDynamicCast( nodeAfter->GetData()
2b5f62a0
VZ
248 ,wxRadioButton
249 );
250
251 if (!pBtn || pBtn->HasFlag(wxRB_GROUP) )
252 {
6e348b12 253 //
2b5f62a0
VZ
254 // No more buttons or the first button of the next group
255 //
256 break;
257 }
b0b5881a 258 pBtn->SetValue(false);
2b5f62a0
VZ
259 }
260 }
3c299c3a 261} // end of wxRadioButton::SetValue
0e320a79 262
97d74dd2
DW
263MRESULT wxRadioButton::OS2WindowProc(
264 WXUINT uMsg
265, WXWPARAM wParam
266, WXLPARAM lParam
267)
268{
269 if (uMsg == WM_SETFOCUS)
270 {
b0b5881a 271 m_bFocusJustSet = true;
97d74dd2
DW
272
273 MRESULT mRc = wxControl::OS2WindowProc( uMsg
274 ,wParam
275 ,lParam
276 );
277
b0b5881a 278 m_bFocusJustSet = false;
97d74dd2
DW
279 return mRc;
280 }
281 return wxControl::OS2WindowProc( uMsg
282 ,wParam
283 ,lParam
284 );
285} // end of wxRadioButton::OS2WindowProc