]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/os2/radiobut.cpp
wxGTK1 : wx/private/eventloopsourcesmanager.h was missing in evtloop.cpp
[wxWidgets.git] / src / os2 / radiobut.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: src/os2/radiobut.cpp
3// Purpose: wxRadioButton
4// Author: David Webster
5// Modified by:
6// Created: 10/12/99
7// Copyright: (c) David Webster
8// Licence: wxWindows licence
9/////////////////////////////////////////////////////////////////////////////
10
11// For compilers that support precompilation, includes "wx.h".
12#include "wx/wxprec.h"
13
14#ifdef __BORLANDC__
15 #pragma hdrstop
16#endif
17
18#include "wx/radiobut.h"
19
20#ifndef WX_PRECOMP
21 #include <stdio.h>
22 #include "wx/brush.h"
23 #include "wx/dcscreen.h"
24 #include "wx/settings.h"
25#endif
26
27#include "wx/os2/private.h"
28
29extern void wxAssociateWinWithHandle( HWND hWnd
30 ,wxWindowOS2* pWin
31 );
32
33void wxRadioButton::Init()
34{
35 m_bFocusJustSet = false;
36} // end of wxRadioButton::Init
37
38void wxRadioButton::Command ( wxCommandEvent& rEvent )
39{
40 SetValue ((rEvent.GetInt() != 0) );
41 ProcessCommand (rEvent);
42} // end of wxRadioButton::Command
43
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 )
52{
53 if ( !CreateControl( pParent
54 ,vId
55 ,rPos
56 ,rSize
57 ,lStyle
58 ,rValidator
59 ,rsName))
60 return false;
61
62 long lSstyle = WS_TABSTOP;
63
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;
79
80 if (HasFlag(wxCLIP_SIBLINGS))
81 lSstyle |= WS_CLIPSIBLINGS;
82
83 if (!OS2CreateControl( wxT("BUTTON")
84 ,lSstyle
85 ,rPos
86 ,rSize
87 ,rsLabel
88 ,0
89 ))
90 return false;
91
92 wxAssociateWinWithHandle(m_hWnd, this);
93 if (HasFlag(wxRB_GROUP))
94 SetValue(true);
95
96 SetFont(*wxSMALL_FONT);
97 SetSize( rPos.x, rPos.y, rSize.x, rSize.y );
98 return true;
99} // end of wxRadioButton::Create
100
101wxSize wxRadioButton::DoGetBestSize() const
102{
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;
106
107 wxString sStr = wxGetWindowText(GetHwnd());
108 int nRadioWidth;
109 int nRadioHeight;
110
111 if (!sStr.empty())
112 {
113 GetTextExtent( sStr
114 ,&nRadioWidth
115 ,&nRadioHeight
116 );
117 nRadioWidth += snRadioSize;
118 if (nRadioHeight < snRadioSize)
119 nRadioHeight = snRadioSize;
120 }
121 else
122 {
123 nRadioWidth = snRadioSize;
124 nRadioHeight = snRadioSize;
125 }
126 return wxSize( nRadioWidth
127 ,nRadioHeight
128 );
129} // end of wxRadioButton::DoGetBestSize
130
131//
132// Get single selection, for single choice list items
133//
134bool wxRadioButton::GetValue() const
135{
136 return((::WinSendMsg((HWND) GetHWND(), BM_QUERYCHECK, (MPARAM)0L, (MPARAM)0L) != 0));
137} // end of wxRadioButton::GetValue
138
139bool wxRadioButton::OS2Command( WXUINT wParam, WXWORD WXUNUSED(wId) )
140{
141 if (wParam != BN_CLICKED)
142 return false;
143
144 if (m_bFocusJustSet)
145 {
146 //
147 // See above: we want to ignore this event
148 //
149 m_bFocusJustSet = false;
150 }
151 else
152 {
153 bool bIsChecked = GetValue();
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 )
163 SetValue(true);
164 }
165 wxCommandEvent rEvent( wxEVT_RADIOBUTTON, m_windowId );
166 rEvent.SetEventObject(this);
167 ProcessCommand(rEvent);
168 }
169 return true;
170} // end of wxRadioButton::OS2Command
171
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 //
181 // to avoid this, we drop the pseudo BN_CLICKED events generated when the
182 // button gains focus
183 m_bFocusJustSet = true;
184
185 wxControl::SetFocus();
186}
187
188void wxRadioButton::SetLabel( const wxString& rsLabel )
189{
190 wxString sLabel = ::wxPMTextToLabel(rsLabel);
191 ::WinSetWindowText((HWND)GetHWND(), (const char *)sLabel.c_str());
192} // end of wxRadioButton::SetLabel
193
194void wxRadioButton::SetValue( bool bValue )
195{
196 ::WinSendMsg((HWND)GetHWND(), BM_SETCHECK, (MPARAM)bValue, (MPARAM)0);
197 if (bValue)
198 {
199 const wxWindowList& rSiblings = GetParent()->GetChildren();
200 wxWindowList::compatibility_iterator nodeThis = rSiblings.Find(this);
201
202 wxCHECK_RET(nodeThis, wxT("radio button not a child of its parent?"));
203
204 //
205 // If it's not the first item of the group ...
206 //
207 if ( !HasFlag(wxRB_GROUP) )
208 {
209 //
210 // ...turn off all radio buttons before this one
211 //
212 for ( wxWindowList::compatibility_iterator nodeBefore = nodeThis->GetPrevious();
213 nodeBefore;
214 nodeBefore = nodeBefore->GetPrevious() )
215 {
216 wxRadioButton* pBtn = wxDynamicCast( nodeBefore->GetData()
217 ,wxRadioButton
218 );
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 }
227 pBtn->SetValue(false);
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 }
236 }
237 }
238
239 //
240 // ... and all after this one
241 //
242 for (wxWindowList::compatibility_iterator nodeAfter = nodeThis->GetNext();
243 nodeAfter;
244 nodeAfter = nodeAfter->GetNext())
245 {
246 wxRadioButton* pBtn = wxDynamicCast( nodeAfter->GetData()
247 ,wxRadioButton
248 );
249
250 if (!pBtn || pBtn->HasFlag(wxRB_GROUP) )
251 {
252 //
253 // No more buttons or the first button of the next group
254 //
255 break;
256 }
257 pBtn->SetValue(false);
258 }
259 }
260} // end of wxRadioButton::SetValue
261
262MRESULT wxRadioButton::OS2WindowProc(
263 WXUINT uMsg
264, WXWPARAM wParam
265, WXLPARAM lParam
266)
267{
268 if (uMsg == WM_SETFOCUS)
269 {
270 m_bFocusJustSet = true;
271
272 MRESULT mRc = wxControl::OS2WindowProc( uMsg
273 ,wParam
274 ,lParam
275 );
276
277 m_bFocusJustSet = false;
278 return mRc;
279 }
280 return wxControl::OS2WindowProc( uMsg
281 ,wParam
282 ,lParam
283 );
284} // end of wxRadioButton::OS2WindowProc