]> git.saurik.com Git - wxWidgets.git/blame - src/univ/checkbox.cpp
added (and documented) msw.xp-tab-ok option
[wxWidgets.git] / src / univ / checkbox.cpp
CommitLineData
1e6feb95
VZ
1/////////////////////////////////////////////////////////////////////////////
2// Name: univ/checkbox.cpp
3// Purpose: wxCheckBox implementation
4// Author: Vadim Zeitlin
5// Modified by:
6// Created: 25.08.00
7// RCS-ID: $Id$
442b35b5 8// Copyright: (c) 2000 SciTech Software, Inc. (www.scitechsoft.com)
65571936 9// Licence: wxWindows licence
1e6feb95
VZ
10/////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
14f355c2 20#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
a3870b2f 21 #pragma implementation "univcheckbox.h"
1e6feb95
VZ
22#endif
23
24#include "wx/wxprec.h"
25
26#ifdef __BORLANDC__
27 #pragma hdrstop
28#endif
29
30#if wxUSE_CHECKBOX
31
32#ifndef WX_PRECOMP
33 #include "wx/dcclient.h"
34 #include "wx/checkbox.h"
35 #include "wx/validate.h"
36
37 #include "wx/button.h" // for wxACTION_BUTTON_XXX
38#endif
39
40#include "wx/univ/theme.h"
41#include "wx/univ/renderer.h"
42#include "wx/univ/inphand.h"
43#include "wx/univ/colschem.h"
44
45// ============================================================================
46// implementation
47// ============================================================================
48
49IMPLEMENT_DYNAMIC_CLASS(wxCheckBox, wxControl)
50
51// ----------------------------------------------------------------------------
52// wxCheckBox
53// ----------------------------------------------------------------------------
54
55void wxCheckBox::Init()
56{
a290fa5a 57 m_isPressed = false;
1e6feb95
VZ
58 m_status = Status_Unchecked;
59}
60
61bool wxCheckBox::Create(wxWindow *parent,
62 wxWindowID id,
63 const wxString &label,
64 const wxPoint &pos,
65 const wxSize &size,
66 long style,
67 const wxValidator& validator,
68 const wxString &name)
69{
61fef19b 70 if ( !wxControl::Create(parent, id, pos, size, style, validator, name) )
a290fa5a 71 return false;
1e6feb95
VZ
72
73 SetLabel(label);
74 SetBestSize(size);
75
76 CreateInputHandler(wxINP_HANDLER_CHECKBOX);
77
a290fa5a 78 return true;
1e6feb95
VZ
79}
80
81// ----------------------------------------------------------------------------
82// checkbox interface
83// ----------------------------------------------------------------------------
84
85bool wxCheckBox::GetValue() const
86{
415a0ff1 87 return (Get3StateValue() != wxCHK_UNCHECKED);
1e6feb95
VZ
88}
89
90void wxCheckBox::SetValue(bool value)
91{
415a0ff1 92 Set3StateValue( value ? wxCHK_CHECKED : wxCHK_UNCHECKED );
1e6feb95
VZ
93}
94
95void wxCheckBox::OnCheck()
96{
97 // we do nothing here
98}
99
100// ----------------------------------------------------------------------------
101// indicator bitmaps
102// ----------------------------------------------------------------------------
103
104wxBitmap wxCheckBox::GetBitmap(State state, Status status) const
105{
106 wxBitmap bmp = m_bitmaps[state][status];
107 if ( !bmp.Ok() )
108 bmp = m_bitmaps[State_Normal][status];
109
110 return bmp;
111}
112
113void wxCheckBox::SetBitmap(const wxBitmap& bmp, State state, Status status)
114{
115 m_bitmaps[state][status] = bmp;
116}
117
118// ----------------------------------------------------------------------------
119// drawing
120// ----------------------------------------------------------------------------
121
122wxCheckBox::State wxCheckBox::GetState(int flags) const
123{
124 if ( flags & wxCONTROL_DISABLED )
125 return State_Disabled;
126 else if ( flags & wxCONTROL_PRESSED )
127 return State_Pressed;
128 else if ( flags & wxCONTROL_CURRENT )
129 return State_Current;
130 else
131 return State_Normal;
132}
133
134void wxCheckBox::DoDraw(wxControlRenderer *renderer)
135{
136 int flags = GetStateFlags();
137
138 wxDC& dc = renderer->GetDC();
139 dc.SetFont(GetFont());
140 dc.SetTextForeground(GetForegroundColour());
141
415a0ff1
WS
142 switch ( Get3StateValue() )
143 {
51e298bb
WS
144 case wxCHK_CHECKED: flags |= wxCONTROL_CHECKED; break;
145 case wxCHK_UNDETERMINED: flags |= wxCONTROL_UNDETERMINED; break;
146 default: /* do nothing */ break;
415a0ff1 147 }
1e6feb95 148
62e1ba75
JS
149 wxBitmap bitmap(GetBitmap(GetState(flags), m_status));
150
1e6feb95
VZ
151 renderer->GetRenderer()->
152 DrawCheckButton(dc,
153 GetLabel(),
62e1ba75 154 bitmap,
1e6feb95
VZ
155 renderer->GetRect(),
156 flags,
157 GetWindowStyle() & wxALIGN_RIGHT ? wxALIGN_RIGHT
158 : wxALIGN_LEFT,
159 GetAccelIndex());
160}
161
162// ----------------------------------------------------------------------------
163// geometry calculations
164// ----------------------------------------------------------------------------
165
166wxSize wxCheckBox::GetBitmapSize() const
167{
168 wxBitmap bmp = GetBitmap(State_Normal, Status_Checked);
169 return bmp.Ok() ? wxSize(bmp.GetWidth(), bmp.GetHeight())
170 : GetRenderer()->GetCheckBitmapSize();
171}
172
173wxSize wxCheckBox::DoGetBestClientSize() const
174{
175 wxClientDC dc(wxConstCast(this, wxCheckBox));
176 dc.SetFont(GetFont());
177 wxCoord width, height;
178 dc.GetMultiLineTextExtent(GetLabel(), &width, &height);
179
180 wxSize sizeBmp = GetBitmapSize();
181 if ( height < sizeBmp.y )
182 height = sizeBmp.y;
183
184#if wxUNIV_COMPATIBLE_MSW
185 // this looks better but is different from what wxMSW does
186 height += GetCharHeight()/2;
187#endif // wxUNIV_COMPATIBLE_MSW
188
189 width += sizeBmp.x + 2*GetCharWidth();
190
191 return wxSize(width, height);
192}
193
194// ----------------------------------------------------------------------------
195// checkbox actions
196// ----------------------------------------------------------------------------
197
415a0ff1
WS
198void wxCheckBox::DoSet3StateValue(wxCheckBoxState state)
199{
200 Status status;
201 switch ( state )
202 {
203 case wxCHK_UNCHECKED: status = Status_Unchecked; break;
204 case wxCHK_CHECKED: status = Status_Checked; break;
205 default: wxFAIL_MSG(_T("Unknown checkbox state"));
206 case wxCHK_UNDETERMINED: status = Status_3rdState; break;
207 }
208 if ( status != m_status )
209 {
210 m_status = status;
211
212 if ( m_status == Status_Checked )
213 {
214 // invoke the hook
215 OnCheck();
216 }
217
218 Refresh();
219 }
220}
221
222wxCheckBoxState wxCheckBox::DoGet3StateValue() const
223{
224 switch ( m_status )
225 {
226 case Status_Checked: return wxCHK_CHECKED;
227 case Status_Unchecked: return wxCHK_UNCHECKED;
51e298bb 228 default: /* go further */ break;
415a0ff1
WS
229 }
230 return wxCHK_UNDETERMINED;
231}
232
1e6feb95
VZ
233void wxCheckBox::Press()
234{
235 if ( !m_isPressed )
236 {
a290fa5a 237 m_isPressed = true;
1e6feb95
VZ
238
239 Refresh();
240 }
241}
242
243void wxCheckBox::Release()
244{
245 if ( m_isPressed )
246 {
a290fa5a 247 m_isPressed = false;
1e6feb95
VZ
248
249 Refresh();
250 }
251}
252
253void wxCheckBox::Toggle()
254{
a290fa5a 255 m_isPressed = false;
1e6feb95 256
415a0ff1
WS
257 Status status = m_status;
258
259 switch ( Get3StateValue() )
260 {
261 case wxCHK_CHECKED:
262 Set3StateValue(Is3rdStateAllowedForUser() ? wxCHK_UNDETERMINED : wxCHK_UNCHECKED);
263 break;
264
265 case wxCHK_UNCHECKED:
266 Set3StateValue(wxCHK_CHECKED);
267 break;
268
269 case wxCHK_UNDETERMINED:
270 Set3StateValue(wxCHK_UNCHECKED);
271 break;
272 }
273
274 if( status != m_status )
275 SendEvent();
1e6feb95
VZ
276}
277
278void wxCheckBox::ChangeValue(bool value)
279{
280 SetValue(value);
281
282 SendEvent();
283}
284
285void wxCheckBox::SendEvent()
286{
287 wxCommandEvent event(wxEVT_COMMAND_CHECKBOX_CLICKED, GetId());
288 InitCommandEvent(event);
415a0ff1
WS
289 wxCheckBoxState state = Get3StateValue();
290
291 // If the style flag to allow the user setting the undetermined state
292 // is not set, then skip the undetermined state and set it to unchecked.
293 if ( state == wxCHK_UNDETERMINED && !Is3rdStateAllowedForUser() )
294 {
295 state = wxCHK_UNCHECKED;
296 Set3StateValue(state);
297 }
298
299 event.SetInt(state);
1e6feb95
VZ
300 Command(event);
301}
302
303// ----------------------------------------------------------------------------
304// input handling
305// ----------------------------------------------------------------------------
306
307bool wxCheckBox::PerformAction(const wxControlAction& action,
308 long numArg,
309 const wxString& strArg)
310{
311 if ( action == wxACTION_BUTTON_PRESS )
312 Press();
313 else if ( action == wxACTION_BUTTON_RELEASE )
314 Release();
315 if ( action == wxACTION_CHECKBOX_CHECK )
a290fa5a 316 ChangeValue(true);
1e6feb95 317 else if ( action == wxACTION_CHECKBOX_CLEAR )
a290fa5a 318 ChangeValue(false);
1e6feb95
VZ
319 else if ( action == wxACTION_CHECKBOX_TOGGLE )
320 Toggle();
321 else
322 return wxControl::PerformAction(action, numArg, strArg);
323
a290fa5a 324 return true;
1e6feb95
VZ
325}
326
327// ----------------------------------------------------------------------------
328// wxStdCheckboxInputHandler
329// ----------------------------------------------------------------------------
330
331wxStdCheckboxInputHandler::wxStdCheckboxInputHandler(wxInputHandler *inphand)
332 : wxStdButtonInputHandler(inphand)
333{
334}
335
23645bfa 336bool wxStdCheckboxInputHandler::HandleActivation(wxInputConsumer *consumer,
61fef19b 337 bool WXUNUSED(activated))
1e6feb95
VZ
338{
339 // only the focused checkbox appearance changes when the app gains/loses
340 // activation
23645bfa 341 return consumer->GetInputWindow()->IsFocused();
1e6feb95
VZ
342}
343
344#endif // wxUSE_CHECKBOX