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