]> git.saurik.com Git - wxWidgets.git/blame - src/univ/checkbox.cpp
added GetIfActive() method returning non-NULL engine only if themes are not only...
[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 {
144 case wxCHK_CHECKED: flags |= wxCONTROL_CHECKED;
145 case wxCHK_UNDETERMINED: flags |= wxCONTROL_UNDETERMINED;
146 }
1e6feb95 147
62e1ba75
JS
148 wxBitmap bitmap(GetBitmap(GetState(flags), m_status));
149
1e6feb95
VZ
150 renderer->GetRenderer()->
151 DrawCheckButton(dc,
152 GetLabel(),
62e1ba75 153 bitmap,
1e6feb95
VZ
154 renderer->GetRect(),
155 flags,
156 GetWindowStyle() & wxALIGN_RIGHT ? wxALIGN_RIGHT
157 : wxALIGN_LEFT,
158 GetAccelIndex());
159}
160
161// ----------------------------------------------------------------------------
162// geometry calculations
163// ----------------------------------------------------------------------------
164
165wxSize wxCheckBox::GetBitmapSize() const
166{
167 wxBitmap bmp = GetBitmap(State_Normal, Status_Checked);
168 return bmp.Ok() ? wxSize(bmp.GetWidth(), bmp.GetHeight())
169 : GetRenderer()->GetCheckBitmapSize();
170}
171
172wxSize wxCheckBox::DoGetBestClientSize() const
173{
174 wxClientDC dc(wxConstCast(this, wxCheckBox));
175 dc.SetFont(GetFont());
176 wxCoord width, height;
177 dc.GetMultiLineTextExtent(GetLabel(), &width, &height);
178
179 wxSize sizeBmp = GetBitmapSize();
180 if ( height < sizeBmp.y )
181 height = sizeBmp.y;
182
183#if wxUNIV_COMPATIBLE_MSW
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;
227 }
228 return wxCHK_UNDETERMINED;
229}
230
1e6feb95
VZ
231void wxCheckBox::Press()
232{
233 if ( !m_isPressed )
234 {
a290fa5a 235 m_isPressed = true;
1e6feb95
VZ
236
237 Refresh();
238 }
239}
240
241void wxCheckBox::Release()
242{
243 if ( m_isPressed )
244 {
a290fa5a 245 m_isPressed = false;
1e6feb95
VZ
246
247 Refresh();
248 }
249}
250
251void wxCheckBox::Toggle()
252{
a290fa5a 253 m_isPressed = false;
1e6feb95 254
415a0ff1
WS
255 Status status = m_status;
256
257 switch ( Get3StateValue() )
258 {
259 case wxCHK_CHECKED:
260 Set3StateValue(Is3rdStateAllowedForUser() ? wxCHK_UNDETERMINED : wxCHK_UNCHECKED);
261 break;
262
263 case wxCHK_UNCHECKED:
264 Set3StateValue(wxCHK_CHECKED);
265 break;
266
267 case wxCHK_UNDETERMINED:
268 Set3StateValue(wxCHK_UNCHECKED);
269 break;
270 }
271
272 if( status != m_status )
273 SendEvent();
1e6feb95
VZ
274}
275
276void wxCheckBox::ChangeValue(bool value)
277{
278 SetValue(value);
279
280 SendEvent();
281}
282
283void wxCheckBox::SendEvent()
284{
285 wxCommandEvent event(wxEVT_COMMAND_CHECKBOX_CLICKED, GetId());
286 InitCommandEvent(event);
415a0ff1
WS
287 wxCheckBoxState state = Get3StateValue();
288
289 // If the style flag to allow the user setting the undetermined state
290 // is not set, then skip the undetermined state and set it to unchecked.
291 if ( state == wxCHK_UNDETERMINED && !Is3rdStateAllowedForUser() )
292 {
293 state = wxCHK_UNCHECKED;
294 Set3StateValue(state);
295 }
296
297 event.SetInt(state);
1e6feb95
VZ
298 Command(event);
299}
300
301// ----------------------------------------------------------------------------
302// input handling
303// ----------------------------------------------------------------------------
304
305bool wxCheckBox::PerformAction(const wxControlAction& action,
306 long numArg,
307 const wxString& strArg)
308{
309 if ( action == wxACTION_BUTTON_PRESS )
310 Press();
311 else if ( action == wxACTION_BUTTON_RELEASE )
312 Release();
313 if ( action == wxACTION_CHECKBOX_CHECK )
a290fa5a 314 ChangeValue(true);
1e6feb95 315 else if ( action == wxACTION_CHECKBOX_CLEAR )
a290fa5a 316 ChangeValue(false);
1e6feb95
VZ
317 else if ( action == wxACTION_CHECKBOX_TOGGLE )
318 Toggle();
319 else
320 return wxControl::PerformAction(action, numArg, strArg);
321
a290fa5a 322 return true;
1e6feb95
VZ
323}
324
325// ----------------------------------------------------------------------------
326// wxStdCheckboxInputHandler
327// ----------------------------------------------------------------------------
328
329wxStdCheckboxInputHandler::wxStdCheckboxInputHandler(wxInputHandler *inphand)
330 : wxStdButtonInputHandler(inphand)
331{
332}
333
23645bfa 334bool wxStdCheckboxInputHandler::HandleActivation(wxInputConsumer *consumer,
61fef19b 335 bool WXUNUSED(activated))
1e6feb95
VZ
336{
337 // only the focused checkbox appearance changes when the app gains/loses
338 // activation
23645bfa 339 return consumer->GetInputWindow()->IsFocused();
1e6feb95
VZ
340}
341
342#endif // wxUSE_CHECKBOX