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