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