]> git.saurik.com Git - wxWidgets.git/commitdiff
added 3-state checkboxes (patch 813790)
authorVadim Zeitlin <vadim@wxwidgets.org>
Sun, 28 Sep 2003 00:23:08 +0000 (00:23 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sun, 28 Sep 2003 00:23:08 +0000 (00:23 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@23982 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

16 files changed:
docs/changes.txt
docs/latex/wx/checkbox.tex
include/wx/checkbox.h
include/wx/mac/checkbox.h
include/wx/msw/checkbox.h
samples/widgets/Makefile.in
samples/widgets/checkbox.cpp [new file with mode: 0644]
samples/widgets/makefile.bcc
samples/widgets/makefile.gcc
samples/widgets/makefile.vc
samples/widgets/makefile.wat
samples/widgets/widgets.bkl
samples/widgets/widgets.dsp
src/mac/carbon/checkbox.cpp
src/mac/checkbox.cpp
src/msw/checkbox.cpp

index c08cfa022ab397d00a5407ae39e64ca66783fed7..049981e0afd3e3c96c75bb3e43ab28e7cf61e767 100644 (file)
@@ -70,6 +70,7 @@ All:
 
 All (GUI):
 
+- added 3-state checkboxes for MSW/Mac (Dimitri Schoolwerth)
 - added some support for C++ exceptions in the library (do read the manual!)
 - added wxListCtrl::GetViewRect()
 - added wxTextCtrl::MarkDirty()
index 673cb679fc1cb4f47ed52b66820da74f5cd4e36b..a47d108e16c13882c253ddd1682487d62031eb0f 100644 (file)
@@ -1,7 +1,8 @@
 \section{\class{wxCheckBox}}\label{wxcheckbox}
 
-A checkbox is a labelled box which is either on (checkmark is visible)
-or off (no checkmark).
+A checkbox is a labelled box which by default is either on (checkmark is visible)
+or off (no checkmark). Optionally (When the wxCHK_3STATE style flag is set) it can have
+a third state, called the mixed or undetermined state. Often this is used as a "Does Not Apply" state.
 
 \wxheading{Derived from}
 
@@ -16,8 +17,12 @@ or off (no checkmark).
 
 \wxheading{Window styles}
 
-\twocolwidtha{5cm}
+\twocolwidtha{7cm}
 \begin{twocollist}\itemsep=0pt
+\twocolitem{\windowstyle{wxCHK\_2STATE}}{Create a 2-state checkbox (This is the default).}
+\twocolitem{\windowstyle{wxCHK\_3STATE}}{Create a 3-state checkbox.}
+\twocolitem{\windowstyle{wxCHK\_ALLOW\_3RD\_STATE\_FOR\_USER}}{By default a user can't set a 3-state checkbox
+to the third state. It can only be done from code. Using this flags allows the user to set the checkbox to the third state by clicking. }
 \twocolitem{\windowstyle{wxALIGN\_RIGHT}}{Makes the text appear on the left of the checkbox.}
 \end{twocollist}
 
@@ -92,11 +97,44 @@ for details.
 
 \constfunc{bool}{GetValue}{\void}
 
-Gets the state of the checkbox.
+Gets the state of a 2-state checkbox.
+
+\wxheading{Return value}
+
+Returns \true if it is checked, \false otherwise.
+
+\membersection{wxCheckBox::Get3StateValue}\label{wxcheckboxgetthreestatevalue}
+
+\constfunc{wxCheckBoxState}{Get3StateValue}{\void}
+
+Gets the state of a 3-state checkbox.
+
+\wxheading{Return value}
+
+Returns wxCHK\_UNCHECKED when the checkbox is unchecked, wxCHK\_CHECKED
+ when it is checked and wxCHK\_UNDETERMINED when it's in the undetermined
+state. Asserts when the function is used with a 2-state checkbox.
+
+\membersection{wxCheckBox::Is3rdStateAllowedForUser}\label{wxcheckboxis3rdstateallowedforuser}
+
+\constfunc{bool}{Is3rdStateAllowedForUser}{\void}
+
+Returns whether or not the user can set the checkbox to the third state.
 
 \wxheading{Return value}
 
-Returns {\tt true} if it is checked, {\tt false} otherwise.
+Returns \true if the user can set the third state of this checkbox, \false if it can only be set
+programmatically or if it's a 2-state checkbox.
+
+\membersection{wxCheckBox::Is3State}\label{wxcheckboxis3state}
+
+\constfunc{bool}{Is3State}{\void}
+
+Returns whether or not the checkbox is a 3-state checkbox.
+
+\wxheading{Return value}
+
+Returns \true if this checkbox is a 3-state checkbox, \false if it's a 2-state checkbox.
 
 \membersection{wxCheckBox::IsChecked}\label{wxcheckboxischecked}
 
@@ -104,7 +142,7 @@ Returns {\tt true} if it is checked, {\tt false} otherwise.
 
 This is just a maybe more readable synonym for 
 \helpref{GetValue}{wxcheckboxgetvalue}: just as the latter, it returns 
-{\tt true} if the checkbox is checked and {\tt false} otherwise.
+\true if the checkbox is checked and \false otherwise.
 
 \membersection{wxCheckBox::SetValue}\label{wxcheckboxsetvalue}
 
@@ -115,5 +153,17 @@ wxEVT\_COMMAND\_CHECKBOX\_CLICKED event to get emitted.
 
 \wxheading{Parameters}
 
-\docparam{state}{If {\tt true}, the check is on, otherwise it is off.}
+\docparam{state}{If \true, the check is on, otherwise it is off.}
+
+\membersection{wxCheckBox::Set3StateValue}\label{wxcheckboxset3statevalue}
+
+\func{void}{Set3StateValue}{\param{const wxCheckBoxState}{ state}}
+
+Sets the checkbox to the given state. This does not cause a
+wxEVT\_COMMAND\_CHECKBOX\_CLICKED event to get emitted.
+
+\wxheading{Parameters}
 
+\docparam{state}{Can be one of: wxCHK\_UNCHECKED (Check is off), wxCHK\_CHECKED
+ (Check is on) or wxCHK\_UNDETERMINED (Check is mixed). Asserts when the checkbox
+ is a 2-state checkbox and setting the state to wxCHK\_UNDETERMINED.}
index a011252b4321a2f423ac916684411374e1af38e6..ac034b8e12c871b08c16e34a5e082d90ffbdaddd 100644 (file)
 
 #include "wx/control.h"
 
-WXDLLEXPORT_DATA(extern const wxChar*) wxCheckBoxNameStr;
+
+/*
+ * wxCheckBox style flags
+ * (Using wxCHK_* because wxCB_* is used by wxComboBox).
+ * Determine whether to use a 3-state or 2-state
+ * checkbox. 3-state enables to differentiate
+ * between 'unchecked', 'checked' and 'undetermined'.
+ */
+#define wxCHK_2STATE           0x0000
+#define wxCHK_3STATE           0x1000
+
+/*
+ * If this style is set the user can set the checkbox to the
+ * undetermined state. If not set the undetermined set can only
+ * be set programmatically.
+ * This style can only be used with 3 state checkboxes.
+ */
+#define wxCHK_ALLOW_3RD_STATE_FOR_USER 0x2000
+
+/*
+ * The possible states of a 3-state checkbox (Compatible
+ * with the 2-state checkbox).
+ */
+enum wxCheckBoxState
+{
+    wxCHK_UNCHECKED,
+    wxCHK_CHECKED,
+    wxCHK_UNDETERMINED /* 3-state checkbox only */
+};
+
+
+WXDLLEXPORT_DATA(extern const wxChar *) wxCheckBoxNameStr;
 
 // ----------------------------------------------------------------------------
 // wxCheckBox: a control which shows a label and a box which may be checked
@@ -30,10 +61,64 @@ public:
     wxCheckBoxBase() { }
 
     // set/get the checked status of the listbox
-    virtual void SetValue(bool value) = 0;
+    virtual void SetValue(const bool value) = 0;
     virtual bool GetValue() const = 0;
 
-    bool IsChecked() const { return GetValue(); }
+    bool IsChecked() const
+    {
+        wxASSERT_MSG( !Is3State(), wxT("Calling IsChecked() doesn't make sense for")
+            wxT(" a three state checkbox, Use Get3StateValue() instead") );
+
+        return GetValue();
+    }
+
+    wxCheckBoxState Get3StateValue() const
+    {
+        wxCheckBoxState state = DoGet3StateValue();
+
+        if ( state == wxCHK_UNDETERMINED && !Is3State() )
+        {
+            // Undetermined state with a 2-state checkbox??
+            wxFAIL_MSG( wxT("DoGet3StateValue() says the 2-state checkbox is ")
+                wxT("in an undetermined/third state") );
+
+            state = wxCHK_UNCHECKED;
+        }
+
+        return state;
+    }
+
+    void Set3StateValue(wxCheckBoxState state)
+    {
+        if ( state == wxCHK_UNDETERMINED && !Is3State() )
+        {
+            wxFAIL_MSG(wxT("Setting a 2-state checkbox to undetermined state"));
+            state = wxCHK_UNCHECKED;
+        }
+
+        DoSet3StateValue(state);
+    }
+
+    bool Is3State() const
+    {
+        return (m_style & wxCHK_3STATE) != 0;
+    }
+
+    bool Is3rdStateAllowedForUser() const
+    {
+        return (m_style & wxCHK_ALLOW_3RD_STATE_FOR_USER) != 0;
+    }
+
+protected:
+    int m_style;
+
+    virtual void DoSet3StateValue(wxCheckBoxState WXUNUSED(state)) { wxFAIL; }
+
+    virtual wxCheckBoxState DoGet3StateValue() const
+    {
+        wxFAIL;
+        return wxCHK_UNCHECKED;
+    }
 
 private:
     DECLARE_NO_COPY_CLASS(wxCheckBoxBase)
index 4677f5dd6679c292c3999b6330425405b451975e..a426cb734bb66cf743bee6f84b534890c63f0ff0 100644 (file)
@@ -37,6 +37,10 @@ public:
             const wxString& name = wxCheckBoxNameStr);
     virtual void SetValue(bool);
     virtual bool GetValue() const;
+
+    void DoSet3StateValue(wxCheckBoxState val);
+    virtual wxCheckBoxState DoGet3StateValue() const;
+
     virtual void MacHandleControlClick( WXWidget control , wxInt16 controlpart , bool mouseStillDown );
     virtual void Command(wxCommandEvent& event);
 
index f3504693bc5834cf8eda8cf2aa71087855345e5d..1d685dfeaf0ce332ae970ec43ea27619fdcc977f 100644 (file)
@@ -42,7 +42,7 @@ public:
                 const wxValidator& validator = wxDefaultValidator,
                 const wxString& name = wxCheckBoxNameStr);
 
-    virtual void SetValue(bool value);
+    virtual void SetValue(const bool value);
     virtual bool GetValue() const;
 
     virtual void SetLabel(const wxString& label);
@@ -53,6 +53,10 @@ public:
 protected:
     virtual wxSize DoGetBestSize() const;
 
+    virtual void DoSet3StateValue(wxCheckBoxState value);
+
+    virtual wxCheckBoxState DoGet3StateValue() const;
+
 private:
     DECLARE_DYNAMIC_CLASS_NO_COPY(wxCheckBox)
 };
index 1c017b35ed66087dc54d371d564e808c0db689fc..cb89c27ae3e9730c10fc6149bd6295feb6566782 100644 (file)
@@ -41,6 +41,7 @@ WIDGETS_CXXFLAGS = $(CPPFLAGS) -D__WX$(TOOLKIT)__ $(__WXUNIV_DEFINE_p) \
        -I$(srcdir)/../../samples $(CXXFLAGS)
 WIDGETS_OBJECTS =  \
        widgets_button.o \
+       widgets_checkbox.o \
        widgets_combobox.o \
        widgets_gauge.o \
        widgets_listbox.o \
@@ -162,6 +163,9 @@ widgets.app/Contents/PkgInfo: widgets$(EXEEXT) $(top_srcdir)/src/mac/Info.plist.
 widgets_button.o: $(srcdir)/button.cpp
        $(CXXC) -c -o $@ $(WIDGETS_CXXFLAGS) $<
 
+widgets_checkbox.o: $(srcdir)/checkbox.cpp
+       $(CXXC) -c -o $@ $(WIDGETS_CXXFLAGS) $<
+
 widgets_combobox.o: $(srcdir)/combobox.cpp
        $(CXXC) -c -o $@ $(WIDGETS_CXXFLAGS) $<
 
diff --git a/samples/widgets/checkbox.cpp b/samples/widgets/checkbox.cpp
new file mode 100644 (file)
index 0000000..8b24262
--- /dev/null
@@ -0,0 +1,160 @@
+/////////////////////////////////////////////////////////////////////////////
+// Program:     wxWindows Widgets Sample
+// Name:        checkbox.cpp
+// Purpose:     Part of the widgets sample showing wxCheckBox
+// Author:      Dimitri Schoolwerth
+// Created:     27 Sep 2003
+// Id:          $Id$
+// Copyright:   (c) 2003 wxWindows team
+// License:     wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+// ============================================================================
+// declarations
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
+// for compilers that support precompilation, includes "wx/wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+// for all others, include the necessary headers
+#ifndef WX_PRECOMP
+    #include "wx/app.h"
+    #include "wx/log.h"
+
+    #include "wx/button.h"
+    #include "wx/checkbox.h"
+
+    #include "wx/sizer.h"
+
+#endif
+
+#include "widgets.h"
+
+#include "icons/checkbox.xpm"
+
+// ----------------------------------------------------------------------------
+// CheckBoxWidgetsPage
+// ----------------------------------------------------------------------------
+
+class CheckBoxWidgetsPage : public WidgetsPage
+{
+public:
+    CheckBoxWidgetsPage(wxNotebook *notebook, wxImageList *imaglist);
+    virtual ~CheckBoxWidgetsPage();
+
+protected:
+    // event handlers
+    void OnCheckBox(wxCommandEvent& event);
+
+    void OnButton(wxCommandEvent& event);
+
+    // the controls
+    // ------------
+
+    wxCheckBox *m_chk2States,
+               *m_chk3States,
+               *m_chk3StatesAllows3rdStateForUser;
+
+    wxButton *m_button;
+
+private:
+    DECLARE_EVENT_TABLE()
+    DECLARE_WIDGETS_PAGE(CheckBoxWidgetsPage)
+};
+
+// ----------------------------------------------------------------------------
+// event tables
+// ----------------------------------------------------------------------------
+
+BEGIN_EVENT_TABLE(CheckBoxWidgetsPage, WidgetsPage)
+    EVT_CHECKBOX(wxID_ANY, CheckBoxWidgetsPage::OnCheckBox)
+    EVT_BUTTON(wxID_ANY, CheckBoxWidgetsPage::OnButton)
+END_EVENT_TABLE()
+
+// ============================================================================
+// implementation
+// ============================================================================
+
+IMPLEMENT_WIDGETS_PAGE(CheckBoxWidgetsPage, wxT("CheckBox"));
+
+CheckBoxWidgetsPage::CheckBoxWidgetsPage(wxNotebook *notebook,
+                                       wxImageList *imaglist)
+                  : WidgetsPage(notebook)
+{
+    imaglist->Add(wxBitmap(checkbox_xpm));
+
+    m_chk2States = new wxCheckBox( this, wxID_ANY,
+        wxT("I'm a standard 2-state checkbox") );
+    m_chk3States = new wxCheckBox( this, wxID_ANY,
+        wxT("I'm a 3-state checkbox that disallows setting the undetermined")
+        wxT(" state by the user" ),
+        wxDefaultPosition, wxDefaultSize, wxCHK_3STATE);
+    m_button = new wxButton( this, wxID_ANY, wxT("&Programmatically set this")
+        wxT(" checkbox to undetermined state") );
+
+    m_chk3StatesAllows3rdStateForUser = new wxCheckBox(this, wxID_ANY,
+        wxT("I'm a 3-state checkbox that allows setting the 3rd state by the user"),
+        wxDefaultPosition, wxDefaultSize, wxCHK_3STATE
+        | wxCHK_ALLOW_3RD_STATE_FOR_USER);
+
+    wxSizer *sizerTop = new wxBoxSizer(wxVERTICAL);
+
+    sizerTop->Add(0, 0, 1, wxEXPAND);
+    sizerTop->Add(m_chk2States, 0, wxEXPAND);
+    sizerTop->Add(0, 0, 1, wxEXPAND);
+    wxSizer *sizerCheckBoxAndButton = new wxBoxSizer(wxHORIZONTAL);
+    {
+        wxSizer *szr = sizerCheckBoxAndButton;
+        szr->Add(m_chk3States, 0, wxEXPAND);
+        szr->Add(0, 0, 1, wxEXPAND);
+        szr->Add(m_button, 0, wxEXPAND);
+
+        sizerTop->Add(szr, 0, wxEXPAND);
+    }
+
+    sizerTop->Add(0, 0, 1, wxEXPAND);
+    sizerTop->Add(m_chk3StatesAllows3rdStateForUser, 0, wxEXPAND);
+    sizerTop->Add(0, 0, 1, wxEXPAND);
+
+    SetSizer(sizerTop);
+
+    sizerTop->Fit(this);
+}
+
+CheckBoxWidgetsPage::~CheckBoxWidgetsPage()
+{
+}
+
+// ----------------------------------------------------------------------------
+// event handlers
+// ----------------------------------------------------------------------------
+
+void CheckBoxWidgetsPage::OnCheckBox(wxCommandEvent& event)
+{
+    static const wxString stateNames[] =
+    {
+        wxT("unchecked"),
+        wxT("checked"),
+        wxT("undetermined/mixed"),
+    };
+    wxCheckBoxState state = (wxCheckBoxState) event.GetInt();
+
+    wxCHECK_RET( (state >= 0) && (state < WXSIZEOF(stateNames)),
+        "event.GetInt() returned an invalid wxCheckBoxState" );
+
+    wxLogMessage(wxT("Checkbox now set to state: %s"),
+        stateNames[state].c_str());
+}
+
+void CheckBoxWidgetsPage::OnButton(wxCommandEvent& WXUNUSED(event))
+{
+    m_chk3States->Set3StateValue(wxCHK_UNDETERMINED);
+}
index aaa9ba15f60192f42ec63e86e24ef85301d7b2c0..a6cfc74bd9b2d2fb3ae710aabb75dd0170f6bc3c 100644 (file)
@@ -30,6 +30,7 @@ WIDGETS_CXXFLAGS = $(CPPFLAGS) $(__RUNTIME_LIBS_6) -I$(BCCDIR)\include \
        -I. $(__DLLFLAG_p) -I.\..\..\samples $(CXXFLAGS)
 WIDGETS_OBJECTS =  \
        $(OBJS)\widgets_button.obj \
+       $(OBJS)\widgets_checkbox.obj \
        $(OBJS)\widgets_combobox.obj \
        $(OBJS)\widgets_gauge.obj \
        $(OBJS)\widgets_listbox.obj \
@@ -166,6 +167,9 @@ all: $(OBJS)\widgets.exe
 $(OBJS)\widgets_button.obj: .\button.cpp
        $(CXX) -q -c -P -o$@ $(WIDGETS_CXXFLAGS) $**
 
+$(OBJS)\widgets_checkbox.obj: .\checkbox.cpp
+       $(CXX) -q -c -P -o$@ $(WIDGETS_CXXFLAGS) $**
+
 $(OBJS)\widgets_combobox.obj: .\combobox.cpp
        $(CXX) -q -c -P -o$@ $(WIDGETS_CXXFLAGS) $**
 
index 951606eee6a4da22ddc440db673682f1008de14b..ee895c66f7400730a565d13e157804b44126acf1 100644 (file)
@@ -23,6 +23,7 @@ WIDGETS_CXXFLAGS = $(CPPFLAGS) $(__DEBUGINFO) $(__OPTIMIZEFLAG_2) $(GCCFLAGS) \
        $(__EXCEPTIONSFLAG_5)
 WIDGETS_OBJECTS =  \
        $(OBJS)\widgets_button.o \
+       $(OBJS)\widgets_checkbox.o \
        $(OBJS)\widgets_combobox.o \
        $(OBJS)\widgets_gauge.o \
        $(OBJS)\widgets_listbox.o \
@@ -173,6 +174,9 @@ all: $(OBJS)\widgets.exe
 $(OBJS)\widgets_button.o: ./button.cpp
        $(CXX) -c -o $@ $(WIDGETS_CXXFLAGS) $<
 
+$(OBJS)\widgets_checkbox.o: ./checkbox.cpp
+       $(CXX) -c -o $@ $(WIDGETS_CXXFLAGS) $<
+
 $(OBJS)\widgets_combobox.o: ./combobox.cpp
        $(CXX) -c -o $@ $(WIDGETS_CXXFLAGS) $<
 
index 9bb4a86d97b29653afee01233a7f951019843da0..eeafbc6e049cefc2f899d112b972be42fd91fd40 100644 (file)
@@ -24,6 +24,7 @@ WIDGETS_CXXFLAGS = $(CPPFLAGS) /M$(__RUNTIME_LIBS_7)$(__DEBUGRUNTIME_3) \
        $(__EXCEPTIONSFLAG_8) $(__EXCEPTIONSFLAG_9)
 WIDGETS_OBJECTS =  \
        $(OBJS)\widgets_button.obj \
+       $(OBJS)\widgets_checkbox.obj \
        $(OBJS)\widgets_combobox.obj \
        $(OBJS)\widgets_gauge.obj \
        $(OBJS)\widgets_listbox.obj \
@@ -254,6 +255,9 @@ all: $(OBJS)\widgets.exe
 $(OBJS)\widgets_button.obj: .\button.cpp
        $(CXX) /c /nologo /TP /Fo$@ $(WIDGETS_CXXFLAGS) $**
 
+$(OBJS)\widgets_checkbox.obj: .\checkbox.cpp
+       $(CXX) /c /nologo /TP /Fo$@ $(WIDGETS_CXXFLAGS) $**
+
 $(OBJS)\widgets_combobox.obj: .\combobox.cpp
        $(CXX) /c /nologo /TP /Fo$@ $(WIDGETS_CXXFLAGS) $**
 
index 932e90f19fc40c9981d4b267b5e370ff0af17707..e48a34ab71c773694dbb487c082770381a8a522e 100644 (file)
@@ -177,6 +177,7 @@ WIDGETS_CXXFLAGS = $(CPPFLAGS) $(__DEBUGINFO_0) $(__OPTIMIZEFLAG_2) -bm &
        -i=.\..\..\samples $(CXXFLAGS) $(__EXCEPTIONSFLAG_7)
 WIDGETS_OBJECTS =  &
        $(OBJS)\widgets_button.obj &
+       $(OBJS)\widgets_checkbox.obj &
        $(OBJS)\widgets_combobox.obj &
        $(OBJS)\widgets_gauge.obj &
        $(OBJS)\widgets_listbox.obj &
@@ -200,6 +201,9 @@ all : .SYMBOLIC $(OBJS)\widgets.exe
 $(OBJS)\widgets_button.obj :  .AUTODEPEND .\button.cpp
        $(CXX) -zq -fo=$^@ $(WIDGETS_CXXFLAGS) $<
 
+$(OBJS)\widgets_checkbox.obj :  .AUTODEPEND .\checkbox.cpp
+       $(CXX) -zq -fo=$^@ $(WIDGETS_CXXFLAGS) $<
+
 $(OBJS)\widgets_combobox.obj :  .AUTODEPEND .\combobox.cpp
        $(CXX) -zq -fo=$^@ $(WIDGETS_CXXFLAGS) $<
 
index 6fe98b16cc27ee9c409d7910d73bb350cd2ccd4a..804049b4bf4e8a84027e7e461148fb643c0eec96 100644 (file)
@@ -4,9 +4,9 @@
     <include file="../../build/bakefiles/common_samples.bkl"/>
 
     <exe id="widgets" template="wx_sample" template_append="wx_append">
-        <sources>button.cpp combobox.cpp gauge.cpp listbox.cpp notebook.cpp
-                 radiobox.cpp slider.cpp spinbtn.cpp static.cpp textctrl.cpp
-                 widgets.cpp</sources>
+        <sources>button.cpp checkbox.cpp combobox.cpp gauge.cpp listbox.cpp
+                 notebook.cpp radiobox.cpp slider.cpp spinbtn.cpp static.cpp
+                 textctrl.cpp widgets.cpp</sources>
         <wx-lib>core</wx-lib>
         <wx-lib>base</wx-lib>
         <win32-res>widgets.rc</win32-res>
index bdd43c33bc9f07e4ce66ccfc533c85a109502427..df59b2de757f370994fa0bf48842c60b0141838a 100644 (file)
@@ -472,6 +472,10 @@ SOURCE=.\button.cpp
 # End Source File
 # Begin Source File
 
+SOURCE=.\checkbox.cpp
+# End Source File
+# Begin Source File
+
 SOURCE=.\combobox.cpp
 # End Source File
 # Begin Source File
index 3df5c00d9e1b795b8a47cb0b8357bae54b8dde9c..7d58ccb1360fdacbeec5a16034024411161d424f 100644 (file)
@@ -34,12 +34,20 @@ bool wxCheckBox::Create(wxWindow *parent, wxWindowID id, const wxString& label,
     if ( !wxCheckBoxBase::Create(parent, id, pos, size, style, validator, name) )
         return false;
 
+    m_style = style;
+
     Rect bounds ;
     Str255 title ;
     
     MacPreControlCreate( parent , id ,  label , pos , size ,style, validator , name , &bounds , title ) ;
 
-    m_macControl = ::NewControl( MAC_WXHWND(parent->MacGetRootWindow()) , &bounds , title , false , 0 , 0 , 1, 
+    SInt16 maxValue = 1 /* kControlCheckboxCheckedValue */;
+    if (style & wxCH_3STATE)
+    {
+        maxValue = 2 /* kControlCheckboxMixedValue */;
+    }
+
+    m_macControl = ::NewControl( MAC_WXHWND(parent->MacGetRootWindow()) , &bounds , title , false , 0 , 0 , maxValue, 
           kControlCheckBoxProc , (long) this ) ;
     
     MacPostControlCreate() ;
@@ -49,26 +57,75 @@ bool wxCheckBox::Create(wxWindow *parent, wxWindowID id, const wxString& label,
 
 void wxCheckBox::SetValue(bool val)
 {
-   ::SetControl32BitValue( (ControlHandle) m_macControl , val ) ;
-   MacRedrawControl() ;
+    if (val)
+    {
+        Set3StateValue(wxCHK_CHECKED);
+    }
+    else
+    {
+        Set3StateValue(wxCHK_UNCHECKED);
+    }
 }
 
 bool wxCheckBox::GetValue() const
 {
-    return ::GetControl32BitValue( (ControlHandle) m_macControl ) ;
+    return (DoGet3StateValue() != 0);
 }
 
 void wxCheckBox::Command (wxCommandEvent & event)
 {
-    SetValue ((event.GetInt() != 0));
-    ProcessCommand (event);
+    int state = event.GetInt();
+
+    wxCHECK_RET( (state == wxCHK_UNCHECKED) || (state == wxCHK_CHECKED)
+        || (state == wxCHK_UNDETERMINED),
+        wxT("event.GetInt() returned an invalid checkbox state") );
+
+    Set3StateValue((wxCheckBoxState) state);
+
+    ProcessCommand(event);
+}
+
+wxCheckBoxState wxCheckBox::DoGet3StateValue() const
+{
+    return (wxCheckBoxState) ::GetControl32BitValue( (ControlHandle) m_macControl );
+}
+
+void wxCheckBox::DoSet3StateValue(wxCheckBoxState val)
+{
+    ::SetControl32BitValue( (ControlHandle) m_macControl , (int) val) ;
+    MacRedrawControl() ;
 }
 
 void wxCheckBox::MacHandleControlClick( WXWidget WXUNUSED(control), wxInt16 WXUNUSED(controlpart) , bool WXUNUSED(mouseStillDown) ) 
 {
-    SetValue( !GetValue() ) ;
     wxCommandEvent event(wxEVT_COMMAND_CHECKBOX_CLICKED, m_windowId );
-    event.SetInt(GetValue());
+    wxCheckBoxState state = Get3StateValue();
+
+    if (state == wxCHK_UNCHECKED)
+    {
+        state = wxCHK_CHECKED;
+    }
+    else if (state == wxCHK_CHECKED)
+    {
+        // If the style flag to allow the user setting the undetermined state
+        // is set, then set the state to undetermined. Otherwise set state to
+        // unchecked.
+        if ( Is3rdStateAllowedForUser() )
+        {
+            state = wxCHK_UNDETERMINED;
+        }
+        else
+        {
+            state = wxCHK_UNCHECKED;
+        }
+    }
+    else if (state == wxCHK_UNDETERMINED)
+    {
+        state = wxCHK_UNCHECKED;
+    }
+        Set3StateValue(state);
+
+    event.SetInt(state);
     event.SetEventObject(this);
     ProcessCommand(event);
 }
index 3df5c00d9e1b795b8a47cb0b8357bae54b8dde9c..7d58ccb1360fdacbeec5a16034024411161d424f 100644 (file)
@@ -34,12 +34,20 @@ bool wxCheckBox::Create(wxWindow *parent, wxWindowID id, const wxString& label,
     if ( !wxCheckBoxBase::Create(parent, id, pos, size, style, validator, name) )
         return false;
 
+    m_style = style;
+
     Rect bounds ;
     Str255 title ;
     
     MacPreControlCreate( parent , id ,  label , pos , size ,style, validator , name , &bounds , title ) ;
 
-    m_macControl = ::NewControl( MAC_WXHWND(parent->MacGetRootWindow()) , &bounds , title , false , 0 , 0 , 1, 
+    SInt16 maxValue = 1 /* kControlCheckboxCheckedValue */;
+    if (style & wxCH_3STATE)
+    {
+        maxValue = 2 /* kControlCheckboxMixedValue */;
+    }
+
+    m_macControl = ::NewControl( MAC_WXHWND(parent->MacGetRootWindow()) , &bounds , title , false , 0 , 0 , maxValue, 
           kControlCheckBoxProc , (long) this ) ;
     
     MacPostControlCreate() ;
@@ -49,26 +57,75 @@ bool wxCheckBox::Create(wxWindow *parent, wxWindowID id, const wxString& label,
 
 void wxCheckBox::SetValue(bool val)
 {
-   ::SetControl32BitValue( (ControlHandle) m_macControl , val ) ;
-   MacRedrawControl() ;
+    if (val)
+    {
+        Set3StateValue(wxCHK_CHECKED);
+    }
+    else
+    {
+        Set3StateValue(wxCHK_UNCHECKED);
+    }
 }
 
 bool wxCheckBox::GetValue() const
 {
-    return ::GetControl32BitValue( (ControlHandle) m_macControl ) ;
+    return (DoGet3StateValue() != 0);
 }
 
 void wxCheckBox::Command (wxCommandEvent & event)
 {
-    SetValue ((event.GetInt() != 0));
-    ProcessCommand (event);
+    int state = event.GetInt();
+
+    wxCHECK_RET( (state == wxCHK_UNCHECKED) || (state == wxCHK_CHECKED)
+        || (state == wxCHK_UNDETERMINED),
+        wxT("event.GetInt() returned an invalid checkbox state") );
+
+    Set3StateValue((wxCheckBoxState) state);
+
+    ProcessCommand(event);
+}
+
+wxCheckBoxState wxCheckBox::DoGet3StateValue() const
+{
+    return (wxCheckBoxState) ::GetControl32BitValue( (ControlHandle) m_macControl );
+}
+
+void wxCheckBox::DoSet3StateValue(wxCheckBoxState val)
+{
+    ::SetControl32BitValue( (ControlHandle) m_macControl , (int) val) ;
+    MacRedrawControl() ;
 }
 
 void wxCheckBox::MacHandleControlClick( WXWidget WXUNUSED(control), wxInt16 WXUNUSED(controlpart) , bool WXUNUSED(mouseStillDown) ) 
 {
-    SetValue( !GetValue() ) ;
     wxCommandEvent event(wxEVT_COMMAND_CHECKBOX_CLICKED, m_windowId );
-    event.SetInt(GetValue());
+    wxCheckBoxState state = Get3StateValue();
+
+    if (state == wxCHK_UNCHECKED)
+    {
+        state = wxCHK_CHECKED;
+    }
+    else if (state == wxCHK_CHECKED)
+    {
+        // If the style flag to allow the user setting the undetermined state
+        // is set, then set the state to undetermined. Otherwise set state to
+        // unchecked.
+        if ( Is3rdStateAllowedForUser() )
+        {
+            state = wxCHK_UNDETERMINED;
+        }
+        else
+        {
+            state = wxCHK_UNCHECKED;
+        }
+    }
+    else if (state == wxCHK_UNDETERMINED)
+    {
+        state = wxCHK_UNCHECKED;
+    }
+        Set3StateValue(state);
+
+    event.SetInt(state);
     event.SetEventObject(this);
     ProcessCommand(event);
 }
index aff1a1301337f23ff1c9f0a8c7fdf581faa1f06f..e8c6ec263ed0b91d63cc8c81812ab19a083e2e4f 100644 (file)
 
 #include "wx/msw/private.h"
 
+#ifndef BST_UNCHECKED
+    #define BST_UNCHECKED 0x0000
+#endif
+
 #ifndef BST_CHECKED
     #define BST_CHECKED 0x0001
 #endif
 
+#ifndef BST_INDETERMINATE
+    #define BST_INDETERMINATE 0x0002
+#endif
+
 // ============================================================================
 // implementation
 // ============================================================================
@@ -66,14 +74,14 @@ wxBEGIN_FLAGS( wxCheckBoxStyle )
     wxFLAGS_MEMBER(wxDOUBLE_BORDER)
     wxFLAGS_MEMBER(wxRAISED_BORDER)
     wxFLAGS_MEMBER(wxSTATIC_BORDER)
-    wxFLAGS_MEMBER(wxBORDER)
+    wxFLAGS_MEMBER(wxNO_BORDER)
 
     // standard window styles
     wxFLAGS_MEMBER(wxTAB_TRAVERSAL)
     wxFLAGS_MEMBER(wxCLIP_CHILDREN)
     wxFLAGS_MEMBER(wxTRANSPARENT_WINDOW)
     wxFLAGS_MEMBER(wxWANTS_CHARS)
-    wxFLAGS_MEMBER(wxFULL_REPAINT_ON_RESIZE)
+    wxFLAGS_MEMBER(wxNO_FULL_REPAINT_ON_RESIZE)
     wxFLAGS_MEMBER(wxALWAYS_SHOW_SB )
     wxFLAGS_MEMBER(wxVSCROLL)
     wxFLAGS_MEMBER(wxHSCROLL)
@@ -107,9 +115,20 @@ IMPLEMENT_DYNAMIC_CLASS(wxCheckBox, wxControl)
 bool wxCheckBox::MSWCommand(WXUINT WXUNUSED(param), WXWORD WXUNUSED(id))
 {
     wxCommandEvent event(wxEVT_COMMAND_CHECKBOX_CLICKED, m_windowId);
-    event.SetInt(GetValue());
+    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);
     event.SetEventObject(this);
     ProcessCommand(event);
+
     return TRUE;
 }
 
@@ -124,9 +143,26 @@ bool wxCheckBox::Create(wxWindow *parent,
     if ( !CreateControl(parent, id, pos, size, style, validator, name) )
         return FALSE;
 
-    long msStyle = BS_AUTOCHECKBOX | WS_TABSTOP;
+    m_style = style;
+
+    long msStyle = WS_TABSTOP;
+
+    if ( style & wxCHK_3STATE )
+    {
+        msStyle |= BS_AUTO3STATE;
+    }
+    else
+    {
+        wxASSERT_MSG( !Is3rdStateAllowedForUser(),
+            wxT("Using wxCH_ALLOW_3RD_STATE_FOR_USER")
+            wxT(" style flag for a 2-state checkbox is useless") );
+        msStyle |= BS_AUTOCHECKBOX;
+    }
+
     if ( style & wxALIGN_RIGHT )
+    {
         msStyle |= BS_LEFTTEXT;
+    }
 
     return MSWCreateControl(wxT("BUTTON"), msStyle, pos, size, label, 0);
 }
@@ -170,18 +206,50 @@ wxSize wxCheckBox::DoGetBestSize() const
 
 void wxCheckBox::SetValue(bool val)
 {
-    SendMessage(GetHwnd(), BM_SETCHECK, val, 0);
+    if (val)
+    {
+        Set3StateValue(wxCHK_CHECKED);
+    }
+    else
+    {
+        Set3StateValue(wxCHK_UNCHECKED);
+    }
 }
 
 bool wxCheckBox::GetValue() const
 {
-    return (SendMessage(GetHwnd(), BM_GETCHECK, 0, 0) & BST_CHECKED) != 0;
+    return (Get3StateValue() != 0);
 }
 
 void wxCheckBox::Command(wxCommandEvent& event)
 {
-    SetValue(event.GetInt() != 0);
+    int state = event.GetInt();
+    wxCHECK_RET( (state == wxCHK_UNCHECKED) || (state == wxCHK_CHECKED)
+        || (state == wxCHK_UNDETERMINED),
+        wxT("event.GetInt() returned an invalid checkbox state") );
+
+    Set3StateValue((wxCheckBoxState) state);
     ProcessCommand(event);
 }
 
+wxCOMPILE_TIME_ASSERT(wxCHK_UNCHECKED == BST_UNCHECKED
+    && wxCHK_CHECKED == BST_CHECKED
+    && wxCHK_UNDETERMINED == BST_INDETERMINATE, EnumValuesIncorrect);
+
+void wxCheckBox::DoSet3StateValue(wxCheckBoxState state)
+{
+    ::SendMessage(GetHwnd(), BM_SETCHECK, (WPARAM) state, 0);
+}
+
+wxCheckBoxState wxCheckBox::DoGet3StateValue() const
+{
+#ifdef __WIN32__
+    return (wxCheckBoxState) ::SendMessage(GetHwnd(), BM_GETCHECK, 0, 0);
+#else
+    return (wxCheckBoxState) ((::SendMessage(GetHwnd(), BM_GETCHECK, 0, 0)
+        & 0x001) == 0x001);
+#endif
+
+}
+
 #endif // wxUSE_CHECKBOX