X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/6aa89a22b8e47000c98bff05c6f545f331f1c353..5fe302ef74b16d8fac0d9458d4658ea5143caaa6:/src/univ/checkbox.cpp diff --git a/src/univ/checkbox.cpp b/src/univ/checkbox.cpp index 78eb261489..520a2edf05 100644 --- a/src/univ/checkbox.cpp +++ b/src/univ/checkbox.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: univ/checkbox.cpp +// Name: src/univ/checkbox.cpp // Purpose: wxCheckBox implementation // Author: Vadim Zeitlin // Modified by: @@ -17,10 +17,6 @@ // headers // ---------------------------------------------------------------------------- -#ifdef __GNUG__ - #pragma implementation "univcheckbox.h" -#endif - #include "wx/wxprec.h" #ifdef __BORLANDC__ @@ -29,9 +25,10 @@ #if wxUSE_CHECKBOX +#include "wx/checkbox.h" + #ifndef WX_PRECOMP #include "wx/dcclient.h" - #include "wx/checkbox.h" #include "wx/validate.h" #include "wx/button.h" // for wxACTION_BUTTON_XXX @@ -42,6 +39,22 @@ #include "wx/univ/inphand.h" #include "wx/univ/colschem.h" +// ---------------------------------------------------------------------------- +// wxStdCheckboxInputHandler: handles the mouse events for the check and radio +// boxes (handling the keyboard input is simple, but its handling differs a +// lot between GTK and MSW, so a new class should be derived for this) +// ---------------------------------------------------------------------------- + +class WXDLLEXPORT wxStdCheckboxInputHandler : public wxStdInputHandler +{ +public: + wxStdCheckboxInputHandler(wxInputHandler *inphand); + + // we have to override this one as wxStdButtonInputHandler version works + // only with the buttons + virtual bool HandleActivation(wxInputConsumer *consumer, bool activated); +}; + // ============================================================================ // implementation // ============================================================================ @@ -54,7 +67,7 @@ IMPLEMENT_DYNAMIC_CLASS(wxCheckBox, wxControl) void wxCheckBox::Init() { - m_isPressed = FALSE; + m_isPressed = false; m_status = Status_Unchecked; } @@ -67,15 +80,15 @@ bool wxCheckBox::Create(wxWindow *parent, const wxValidator& validator, const wxString &name) { - if ( !wxControl::Create(parent, id, pos, size, style, wxDefaultValidator, name) ) - return FALSE; + if ( !wxControl::Create(parent, id, pos, size, style, validator, name) ) + return false; SetLabel(label); - SetBestSize(size); + SetInitialSize(size); CreateInputHandler(wxINP_HANDLER_CHECKBOX); - return TRUE; + return true; } // ---------------------------------------------------------------------------- @@ -84,24 +97,12 @@ bool wxCheckBox::Create(wxWindow *parent, bool wxCheckBox::GetValue() const { - return m_status == Status_Checked; + return (Get3StateValue() != wxCHK_UNCHECKED); } void wxCheckBox::SetValue(bool value) { - Status status = value ? Status_Checked : Status_Unchecked; - if ( status != m_status ) - { - m_status = status; - - if ( m_status == Status_Checked ) - { - // invoke the hook - OnCheck(); - } - - Refresh(); - } + Set3StateValue( value ? wxCHK_CHECKED : wxCHK_UNCHECKED ); } void wxCheckBox::OnCheck() @@ -151,8 +152,12 @@ void wxCheckBox::DoDraw(wxControlRenderer *renderer) dc.SetFont(GetFont()); dc.SetTextForeground(GetForegroundColour()); - if ( m_status == Status_Checked ) - flags |= wxCONTROL_CHECKED; + switch ( Get3StateValue() ) + { + case wxCHK_CHECKED: flags |= wxCONTROL_CHECKED; break; + case wxCHK_UNDETERMINED: flags |= wxCONTROL_UNDETERMINED; break; + default: /* do nothing */ break; + } wxBitmap bitmap(GetBitmap(GetState(flags), m_status)); @@ -189,7 +194,9 @@ wxSize wxCheckBox::DoGetBestClientSize() const if ( height < sizeBmp.y ) height = sizeBmp.y; -#if wxUNIV_COMPATIBLE_MSW +#if defined(wxUNIV_COMPATIBLE_MSW) && wxUNIV_COMPATIBLE_MSW + // FIXME: flag nowhere defined so perhaps should be removed? + // this looks better but is different from what wxMSW does height += GetCharHeight()/2; #endif // wxUNIV_COMPATIBLE_MSW @@ -203,11 +210,46 @@ wxSize wxCheckBox::DoGetBestClientSize() const // checkbox actions // ---------------------------------------------------------------------------- +void wxCheckBox::DoSet3StateValue(wxCheckBoxState state) +{ + Status status; + switch ( state ) + { + case wxCHK_UNCHECKED: status = Status_Unchecked; break; + case wxCHK_CHECKED: status = Status_Checked; break; + default: wxFAIL_MSG(_T("Unknown checkbox state")); + case wxCHK_UNDETERMINED: status = Status_3rdState; break; + } + if ( status != m_status ) + { + m_status = status; + + if ( m_status == Status_Checked ) + { + // invoke the hook + OnCheck(); + } + + Refresh(); + } +} + +wxCheckBoxState wxCheckBox::DoGet3StateValue() const +{ + switch ( m_status ) + { + case Status_Checked: return wxCHK_CHECKED; + case Status_Unchecked: return wxCHK_UNCHECKED; + default: /* go further */ break; + } + return wxCHK_UNDETERMINED; +} + void wxCheckBox::Press() { if ( !m_isPressed ) { - m_isPressed = TRUE; + m_isPressed = true; Refresh(); } @@ -217,7 +259,7 @@ void wxCheckBox::Release() { if ( m_isPressed ) { - m_isPressed = FALSE; + m_isPressed = false; Refresh(); } @@ -225,9 +267,27 @@ void wxCheckBox::Release() void wxCheckBox::Toggle() { - m_isPressed = FALSE; + m_isPressed = false; + + Status status = m_status; + + switch ( Get3StateValue() ) + { + case wxCHK_CHECKED: + Set3StateValue(Is3rdStateAllowedForUser() ? wxCHK_UNDETERMINED : wxCHK_UNCHECKED); + break; - ChangeValue(!GetValue()); + case wxCHK_UNCHECKED: + Set3StateValue(wxCHK_CHECKED); + break; + + case wxCHK_UNDETERMINED: + Set3StateValue(wxCHK_UNCHECKED); + break; + } + + if( status != m_status ) + SendEvent(); } void wxCheckBox::ChangeValue(bool value) @@ -241,7 +301,17 @@ void wxCheckBox::SendEvent() { wxCommandEvent event(wxEVT_COMMAND_CHECKBOX_CLICKED, GetId()); InitCommandEvent(event); - event.SetInt(IsChecked()); + wxCheckBoxState state = Get3StateValue(); + + // If the style flag to allow the user setting the undetermined state + // is not set, then skip the undetermined state and set it to unchecked. + if ( state == wxCHK_UNDETERMINED && !Is3rdStateAllowedForUser() ) + { + state = wxCHK_UNCHECKED; + Set3StateValue(state); + } + + event.SetInt(state); Command(event); } @@ -258,28 +328,36 @@ bool wxCheckBox::PerformAction(const wxControlAction& action, else if ( action == wxACTION_BUTTON_RELEASE ) Release(); if ( action == wxACTION_CHECKBOX_CHECK ) - ChangeValue(TRUE); + ChangeValue(true); else if ( action == wxACTION_CHECKBOX_CLEAR ) - ChangeValue(FALSE); + ChangeValue(false); else if ( action == wxACTION_CHECKBOX_TOGGLE ) Toggle(); else return wxControl::PerformAction(action, numArg, strArg); - return TRUE; + return true; +} + +/* static */ +wxInputHandler *wxCheckBox::CreateStdInputHandler(wxInputHandler *handlerDef) +{ + static wxStdCheckboxInputHandler s_handler(handlerDef); + + return &s_handler; } // ---------------------------------------------------------------------------- // wxStdCheckboxInputHandler // ---------------------------------------------------------------------------- -wxStdCheckboxInputHandler::wxStdCheckboxInputHandler(wxInputHandler *inphand) - : wxStdButtonInputHandler(inphand) +wxStdCheckboxInputHandler::wxStdCheckboxInputHandler(wxInputHandler *def) + : wxStdInputHandler(wxButton::GetStdInputHandler(def)) { } bool wxStdCheckboxInputHandler::HandleActivation(wxInputConsumer *consumer, - bool activated) + bool WXUNUSED(activated)) { // only the focused checkbox appearance changes when the app gains/loses // activation