1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/univ/checkbox.cpp
3 // Purpose: wxCheckBox implementation
4 // Author: Vadim Zeitlin
8 // Copyright: (c) 2000 SciTech Software, Inc. (www.scitechsoft.com)
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 #include "wx/wxprec.h"
28 #include "wx/checkbox.h"
31 #include "wx/dcclient.h"
32 #include "wx/validate.h"
34 #include "wx/button.h" // for wxACTION_BUTTON_XXX
37 #include "wx/univ/theme.h"
38 #include "wx/univ/renderer.h"
39 #include "wx/univ/inphand.h"
40 #include "wx/univ/colschem.h"
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 // ----------------------------------------------------------------------------
48 class WXDLLEXPORT wxStdCheckboxInputHandler
: public wxStdInputHandler
51 wxStdCheckboxInputHandler(wxInputHandler
*inphand
);
53 // we have to override this one as wxStdButtonInputHandler version works
54 // only with the buttons
55 virtual bool HandleActivation(wxInputConsumer
*consumer
, bool activated
);
58 // ============================================================================
60 // ============================================================================
62 // ----------------------------------------------------------------------------
64 // ----------------------------------------------------------------------------
66 void wxCheckBox::Init()
69 m_status
= Status_Unchecked
;
72 bool wxCheckBox::Create(wxWindow
*parent
,
74 const wxString
&label
,
78 const wxValidator
& validator
,
81 WXValidateStyle( &style
);
82 if ( !wxControl::Create(parent
, id
, pos
, size
, style
, validator
, name
) )
88 CreateInputHandler(wxINP_HANDLER_CHECKBOX
);
93 // ----------------------------------------------------------------------------
95 // ----------------------------------------------------------------------------
97 bool wxCheckBox::GetValue() const
99 return (Get3StateValue() != wxCHK_UNCHECKED
);
102 void wxCheckBox::SetValue(bool value
)
104 Set3StateValue( value
? wxCHK_CHECKED
: wxCHK_UNCHECKED
);
107 void wxCheckBox::OnCheck()
109 // we do nothing here
112 // ----------------------------------------------------------------------------
114 // ----------------------------------------------------------------------------
116 wxBitmap
wxCheckBox::GetBitmap(State state
, Status status
) const
118 wxBitmap bmp
= m_bitmaps
[state
][status
];
120 bmp
= m_bitmaps
[State_Normal
][status
];
125 void wxCheckBox::SetBitmap(const wxBitmap
& bmp
, State state
, Status status
)
127 m_bitmaps
[state
][status
] = bmp
;
130 // ----------------------------------------------------------------------------
132 // ----------------------------------------------------------------------------
134 wxCheckBox::State
wxCheckBox::GetState(int flags
) const
136 if ( flags
& wxCONTROL_DISABLED
)
137 return State_Disabled
;
138 else if ( flags
& wxCONTROL_PRESSED
)
139 return State_Pressed
;
140 else if ( flags
& wxCONTROL_CURRENT
)
141 return State_Current
;
146 void wxCheckBox::DoDraw(wxControlRenderer
*renderer
)
148 int flags
= GetStateFlags();
150 wxDC
& dc
= renderer
->GetDC();
151 dc
.SetFont(GetFont());
152 dc
.SetTextForeground(GetForegroundColour());
154 switch ( Get3StateValue() )
156 case wxCHK_CHECKED
: flags
|= wxCONTROL_CHECKED
; break;
157 case wxCHK_UNDETERMINED
: flags
|= wxCONTROL_UNDETERMINED
; break;
158 default: /* do nothing */ break;
161 wxBitmap
bitmap(GetBitmap(GetState(flags
), m_status
));
163 renderer
->GetRenderer()->
169 GetWindowStyle() & wxALIGN_RIGHT
? wxALIGN_RIGHT
174 // ----------------------------------------------------------------------------
175 // geometry calculations
176 // ----------------------------------------------------------------------------
178 wxSize
wxCheckBox::GetBitmapSize() const
180 wxBitmap bmp
= GetBitmap(State_Normal
, Status_Checked
);
181 return bmp
.Ok() ? wxSize(bmp
.GetWidth(), bmp
.GetHeight())
182 : GetRenderer()->GetCheckBitmapSize();
185 wxSize
wxCheckBox::DoGetBestClientSize() const
187 wxClientDC
dc(wxConstCast(this, wxCheckBox
));
188 dc
.SetFont(GetFont());
189 wxCoord width
, height
;
190 dc
.GetMultiLineTextExtent(GetLabel(), &width
, &height
);
192 wxSize sizeBmp
= GetBitmapSize();
193 if ( height
< sizeBmp
.y
)
196 #if defined(wxUNIV_COMPATIBLE_MSW) && wxUNIV_COMPATIBLE_MSW
197 // FIXME: flag nowhere defined so perhaps should be removed?
199 // this looks better but is different from what wxMSW does
200 height
+= GetCharHeight()/2;
201 #endif // wxUNIV_COMPATIBLE_MSW
203 width
+= sizeBmp
.x
+ 2*GetCharWidth();
205 return wxSize(width
, height
);
208 // ----------------------------------------------------------------------------
210 // ----------------------------------------------------------------------------
212 void wxCheckBox::DoSet3StateValue(wxCheckBoxState state
)
217 case wxCHK_UNCHECKED
: status
= Status_Unchecked
; break;
218 case wxCHK_CHECKED
: status
= Status_Checked
; break;
219 default: wxFAIL_MSG(wxT("Unknown checkbox state"));
220 case wxCHK_UNDETERMINED
: status
= Status_3rdState
; break;
222 if ( status
!= m_status
)
226 if ( m_status
== Status_Checked
)
236 wxCheckBoxState
wxCheckBox::DoGet3StateValue() const
240 case Status_Checked
: return wxCHK_CHECKED
;
241 case Status_Unchecked
: return wxCHK_UNCHECKED
;
242 default: /* go further */ break;
244 return wxCHK_UNDETERMINED
;
247 void wxCheckBox::Press()
257 void wxCheckBox::Release()
267 void wxCheckBox::Toggle()
271 Status status
= m_status
;
273 switch ( Get3StateValue() )
276 Set3StateValue(Is3rdStateAllowedForUser() ? wxCHK_UNDETERMINED
: wxCHK_UNCHECKED
);
279 case wxCHK_UNCHECKED
:
280 Set3StateValue(wxCHK_CHECKED
);
283 case wxCHK_UNDETERMINED
:
284 Set3StateValue(wxCHK_UNCHECKED
);
288 if( status
!= m_status
)
292 void wxCheckBox::ChangeValue(bool value
)
299 void wxCheckBox::SendEvent()
301 wxCommandEvent
event(wxEVT_COMMAND_CHECKBOX_CLICKED
, GetId());
302 InitCommandEvent(event
);
303 wxCheckBoxState state
= Get3StateValue();
305 // If the style flag to allow the user setting the undetermined state
306 // is not set, then skip the undetermined state and set it to unchecked.
307 if ( state
== wxCHK_UNDETERMINED
&& !Is3rdStateAllowedForUser() )
309 state
= wxCHK_UNCHECKED
;
310 Set3StateValue(state
);
317 // ----------------------------------------------------------------------------
319 // ----------------------------------------------------------------------------
321 bool wxCheckBox::PerformAction(const wxControlAction
& action
,
323 const wxString
& strArg
)
325 if ( action
== wxACTION_BUTTON_PRESS
)
327 else if ( action
== wxACTION_BUTTON_RELEASE
)
329 if ( action
== wxACTION_CHECKBOX_CHECK
)
331 else if ( action
== wxACTION_CHECKBOX_CLEAR
)
333 else if ( action
== wxACTION_CHECKBOX_TOGGLE
)
336 return wxControl::PerformAction(action
, numArg
, strArg
);
342 wxInputHandler
*wxCheckBox::CreateStdInputHandler(wxInputHandler
*handlerDef
)
344 static wxStdCheckboxInputHandler
s_handler(handlerDef
);
349 // ----------------------------------------------------------------------------
350 // wxStdCheckboxInputHandler
351 // ----------------------------------------------------------------------------
353 wxStdCheckboxInputHandler::wxStdCheckboxInputHandler(wxInputHandler
*def
)
354 : wxStdInputHandler(wxButton::GetStdInputHandler(def
))
358 bool wxStdCheckboxInputHandler::HandleActivation(wxInputConsumer
*consumer
,
359 bool WXUNUSED(activated
))
361 // only the focused checkbox appearance changes when the app gains/loses
363 return consumer
->GetInputWindow()->IsFocused();
366 #endif // wxUSE_CHECKBOX