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