1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/univ/checkbox.cpp
3 // Purpose: wxCheckBox implementation
4 // Author: Vadim Zeitlin
7 // Copyright: (c) 2000 SciTech Software, Inc. (www.scitechsoft.com)
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 // ============================================================================
13 // ============================================================================
15 // ----------------------------------------------------------------------------
17 // ----------------------------------------------------------------------------
19 #include "wx/wxprec.h"
27 #include "wx/checkbox.h"
30 #include "wx/dcclient.h"
31 #include "wx/validate.h"
33 #include "wx/button.h" // for wxACTION_BUTTON_XXX
36 #include "wx/univ/theme.h"
37 #include "wx/univ/renderer.h"
38 #include "wx/univ/inphand.h"
39 #include "wx/univ/colschem.h"
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 // ----------------------------------------------------------------------------
47 class WXDLLEXPORT wxStdCheckboxInputHandler
: public wxStdInputHandler
50 wxStdCheckboxInputHandler(wxInputHandler
*inphand
);
52 // we have to override this one as wxStdButtonInputHandler version works
53 // only with the buttons
54 virtual bool HandleActivation(wxInputConsumer
*consumer
, bool activated
);
57 // ============================================================================
59 // ============================================================================
61 // ----------------------------------------------------------------------------
63 // ----------------------------------------------------------------------------
65 void wxCheckBox::Init()
68 m_status
= Status_Unchecked
;
71 bool wxCheckBox::Create(wxWindow
*parent
,
73 const wxString
&label
,
77 const wxValidator
& validator
,
80 WXValidateStyle( &style
);
81 if ( !wxControl::Create(parent
, id
, pos
, size
, style
, validator
, name
) )
87 CreateInputHandler(wxINP_HANDLER_CHECKBOX
);
92 // ----------------------------------------------------------------------------
94 // ----------------------------------------------------------------------------
96 bool wxCheckBox::GetValue() const
98 return (Get3StateValue() != wxCHK_UNCHECKED
);
101 void wxCheckBox::SetValue(bool value
)
103 Set3StateValue( value
? wxCHK_CHECKED
: wxCHK_UNCHECKED
);
106 void wxCheckBox::OnCheck()
108 // we do nothing here
111 // ----------------------------------------------------------------------------
113 // ----------------------------------------------------------------------------
115 wxBitmap
wxCheckBox::GetBitmap(State state
, Status status
) const
117 wxBitmap bmp
= m_bitmaps
[state
][status
];
119 bmp
= m_bitmaps
[State_Normal
][status
];
124 void wxCheckBox::SetBitmap(const wxBitmap
& bmp
, State state
, Status status
)
126 m_bitmaps
[state
][status
] = bmp
;
129 // ----------------------------------------------------------------------------
131 // ----------------------------------------------------------------------------
133 wxCheckBox::State
wxCheckBox::GetState(int flags
) const
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
;
145 void wxCheckBox::DoDraw(wxControlRenderer
*renderer
)
147 int flags
= GetStateFlags();
149 wxDC
& dc
= renderer
->GetDC();
150 dc
.SetFont(GetFont());
151 dc
.SetTextForeground(GetForegroundColour());
153 switch ( Get3StateValue() )
155 case wxCHK_CHECKED
: flags
|= wxCONTROL_CHECKED
; break;
156 case wxCHK_UNDETERMINED
: flags
|= wxCONTROL_UNDETERMINED
; break;
157 default: /* do nothing */ break;
160 wxBitmap
bitmap(GetBitmap(GetState(flags
), m_status
));
162 renderer
->GetRenderer()->
168 GetWindowStyle() & wxALIGN_RIGHT
? wxALIGN_RIGHT
173 // ----------------------------------------------------------------------------
174 // geometry calculations
175 // ----------------------------------------------------------------------------
177 wxSize
wxCheckBox::GetBitmapSize() const
179 wxBitmap bmp
= GetBitmap(State_Normal
, Status_Checked
);
180 return bmp
.IsOk() ? wxSize(bmp
.GetWidth(), bmp
.GetHeight())
181 : GetRenderer()->GetCheckBitmapSize();
184 wxSize
wxCheckBox::DoGetBestClientSize() const
186 wxClientDC
dc(wxConstCast(this, wxCheckBox
));
187 dc
.SetFont(GetFont());
188 wxCoord width
, height
;
189 dc
.GetMultiLineTextExtent(GetLabel(), &width
, &height
);
191 wxSize sizeBmp
= GetBitmapSize();
192 if ( height
< sizeBmp
.y
)
195 #if defined(wxUNIV_COMPATIBLE_MSW) && wxUNIV_COMPATIBLE_MSW
196 // FIXME: flag nowhere defined so perhaps should be removed?
198 // this looks better but is different from what wxMSW does
199 height
+= GetCharHeight()/2;
200 #endif // wxUNIV_COMPATIBLE_MSW
202 width
+= sizeBmp
.x
+ 2*GetCharWidth();
204 return wxSize(width
, height
);
207 // ----------------------------------------------------------------------------
209 // ----------------------------------------------------------------------------
211 void wxCheckBox::DoSet3StateValue(wxCheckBoxState state
)
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;
221 if ( status
!= m_status
)
225 if ( m_status
== Status_Checked
)
235 wxCheckBoxState
wxCheckBox::DoGet3StateValue() const
239 case Status_Checked
: return wxCHK_CHECKED
;
240 case Status_Unchecked
: return wxCHK_UNCHECKED
;
241 default: /* go further */ break;
243 return wxCHK_UNDETERMINED
;
246 void wxCheckBox::Press()
256 void wxCheckBox::Release()
266 void wxCheckBox::Toggle()
270 Status status
= m_status
;
272 switch ( Get3StateValue() )
275 Set3StateValue(Is3rdStateAllowedForUser() ? wxCHK_UNDETERMINED
: wxCHK_UNCHECKED
);
278 case wxCHK_UNCHECKED
:
279 Set3StateValue(wxCHK_CHECKED
);
282 case wxCHK_UNDETERMINED
:
283 Set3StateValue(wxCHK_UNCHECKED
);
287 if( status
!= m_status
)
291 void wxCheckBox::ChangeValue(bool value
)
298 void wxCheckBox::SendEvent()
300 wxCommandEvent
event(wxEVT_CHECKBOX
, GetId());
301 InitCommandEvent(event
);
302 wxCheckBoxState state
= Get3StateValue();
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() )
308 state
= wxCHK_UNCHECKED
;
309 Set3StateValue(state
);
316 // ----------------------------------------------------------------------------
318 // ----------------------------------------------------------------------------
320 bool wxCheckBox::PerformAction(const wxControlAction
& action
,
322 const wxString
& strArg
)
324 if ( action
== wxACTION_BUTTON_PRESS
)
326 else if ( action
== wxACTION_BUTTON_RELEASE
)
328 if ( action
== wxACTION_CHECKBOX_CHECK
)
330 else if ( action
== wxACTION_CHECKBOX_CLEAR
)
332 else if ( action
== wxACTION_CHECKBOX_TOGGLE
)
335 return wxControl::PerformAction(action
, numArg
, strArg
);
341 wxInputHandler
*wxCheckBox::CreateStdInputHandler(wxInputHandler
*handlerDef
)
343 static wxStdCheckboxInputHandler
s_handler(handlerDef
);
348 // ----------------------------------------------------------------------------
349 // wxStdCheckboxInputHandler
350 // ----------------------------------------------------------------------------
352 wxStdCheckboxInputHandler::wxStdCheckboxInputHandler(wxInputHandler
*def
)
353 : wxStdInputHandler(wxButton::GetStdInputHandler(def
))
357 bool wxStdCheckboxInputHandler::HandleActivation(wxInputConsumer
*consumer
,
358 bool WXUNUSED(activated
))
360 // only the focused checkbox appearance changes when the app gains/loses
362 return consumer
->GetInputWindow()->IsFocused();
365 #endif // wxUSE_CHECKBOX