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