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
.IsOk() ? 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_CHECKBOX
, 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