]> git.saurik.com Git - wxWidgets.git/commitdiff
3rd state in checkboxes for wxUniv [closes bug#1040585].
authorWłodzimierz Skiba <abx@abx.art.pl>
Thu, 18 Nov 2004 13:16:41 +0000 (13:16 +0000)
committerWłodzimierz Skiba <abx@abx.art.pl>
Thu, 18 Nov 2004 13:16:41 +0000 (13:16 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@30603 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

docs/changes.txt
include/wx/renderer.h
include/wx/univ/checkbox.h
src/univ/checkbox.cpp
src/univ/themes/gtk.cpp
src/univ/themes/win32.cpp

index 7473446f256544f2bb15cc2cbdafaea93c674a82..48796171e193332ba5cc1fccf1b57f1caf3dfc7c 100644 (file)
@@ -263,6 +263,7 @@ wxUniv:
 
 - wxBU_... button align flags support
 - vertical notebook orientation support
 
 - wxBU_... button align flags support
 - vertical notebook orientation support
+- 3rd state support for checkboxes
 
 
 2.5.3
 
 
 2.5.3
index 1a14e5fb4bb630fda2df9246c5066ef8722b494c..271f19dcada8076cbd9ef5bb6a4140b32c52a891 100644 (file)
@@ -54,6 +54,7 @@ enum
     wxCONTROL_SELECTED   = 0x00000020,  // selected item in e.g. listbox
     wxCONTROL_CHECKED    = 0x00000040,  // (check/radio button) is checked
     wxCONTROL_CHECKABLE  = 0x00000080,  // (menu) item can be checked
     wxCONTROL_SELECTED   = 0x00000020,  // selected item in e.g. listbox
     wxCONTROL_CHECKED    = 0x00000040,  // (check/radio button) is checked
     wxCONTROL_CHECKABLE  = 0x00000080,  // (menu) item can be checked
+    wxCONTROL_UNDETERMINED = wxCONTROL_CHECKABLE, // (check) undetermined state
 
     wxCONTROL_FLAGS_MASK = 0x000000ff,
 
 
     wxCONTROL_FLAGS_MASK = 0x000000ff,
 
index c7aa666d15e010fb4f927af7d4bbf89d7dde089d..9c6108fac9ab74defadfd1f458815cf8acee0343 100644 (file)
@@ -54,7 +54,7 @@ public:
     {
         Status_Checked,
         Status_Unchecked,
     {
         Status_Checked,
         Status_Unchecked,
-        Status_Unknown,
+        Status_3rdState,
         Status_Max
     };
 
         Status_Max
     };
 
@@ -102,8 +102,11 @@ public:
     virtual bool IsPressed() const { return m_isPressed; }
 
     virtual bool HasTransparentBackground() { return true; }
     virtual bool IsPressed() const { return m_isPressed; }
 
     virtual bool HasTransparentBackground() { return true; }
-    
+
 protected:
 protected:
+    virtual void DoSet3StateValue(wxCheckBoxState WXUNUSED(state));
+    virtual wxCheckBoxState DoGet3StateValue() const;
+
     virtual bool PerformAction(const wxControlAction& action,
                                long numArg = -1,
                                const wxString& strArg = wxEmptyString);
     virtual bool PerformAction(const wxControlAction& action,
                                long numArg = -1,
                                const wxString& strArg = wxEmptyString);
index 450d303dc1f343c111b34892a423778875956061..fa84b05a95d2ac82a9824ed3bc41f46bd371879e 100644 (file)
@@ -84,24 +84,12 @@ bool wxCheckBox::Create(wxWindow *parent,
 
 bool wxCheckBox::GetValue() const
 {
 
 bool wxCheckBox::GetValue() const
 {
-    return m_status == Status_Checked;
+    return (Get3StateValue() != wxCHK_UNCHECKED);
 }
 
 void wxCheckBox::SetValue(bool value)
 {
 }
 
 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()
 }
 
 void wxCheckBox::OnCheck()
@@ -151,8 +139,11 @@ void wxCheckBox::DoDraw(wxControlRenderer *renderer)
     dc.SetFont(GetFont());
     dc.SetTextForeground(GetForegroundColour());
 
     dc.SetFont(GetFont());
     dc.SetTextForeground(GetForegroundColour());
 
-    if ( m_status == Status_Checked )
-        flags |= wxCONTROL_CHECKED;
+    switch ( Get3StateValue() )
+    {
+        case wxCHK_CHECKED:      flags |= wxCONTROL_CHECKED;
+        case wxCHK_UNDETERMINED: flags |= wxCONTROL_UNDETERMINED;
+    }
 
     wxBitmap bitmap(GetBitmap(GetState(flags), m_status));
 
 
     wxBitmap bitmap(GetBitmap(GetState(flags), m_status));
 
@@ -203,6 +194,40 @@ wxSize wxCheckBox::DoGetBestClientSize() const
 // checkbox actions
 // ----------------------------------------------------------------------------
 
 // 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;
+    }
+    return wxCHK_UNDETERMINED;
+}
+
 void wxCheckBox::Press()
 {
     if ( !m_isPressed )
 void wxCheckBox::Press()
 {
     if ( !m_isPressed )
@@ -227,7 +252,25 @@ void wxCheckBox::Toggle()
 {
     m_isPressed = false;
 
 {
     m_isPressed = false;
 
-    ChangeValue(!GetValue());
+    Status status = m_status;
+
+    switch ( Get3StateValue() )
+    {
+        case wxCHK_CHECKED:
+            Set3StateValue(Is3rdStateAllowedForUser() ? wxCHK_UNDETERMINED : wxCHK_UNCHECKED);
+            break;
+
+        case wxCHK_UNCHECKED:
+            Set3StateValue(wxCHK_CHECKED);
+            break;
+
+        case wxCHK_UNDETERMINED:
+            Set3StateValue(wxCHK_UNCHECKED);
+            break;
+    }
+
+    if( status != m_status )
+        SendEvent();
 }
 
 void wxCheckBox::ChangeValue(bool value)
 }
 
 void wxCheckBox::ChangeValue(bool value)
@@ -241,7 +284,17 @@ void wxCheckBox::SendEvent()
 {
     wxCommandEvent event(wxEVT_COMMAND_CHECKBOX_CLICKED, GetId());
     InitCommandEvent(event);
 {
     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);
 }
 
     Command(event);
 }
 
index 7dddfa2cddcb3723abfc513e643de8d0afcd02be..ecfebabec1edf2e1a81111ca285cc7f6ef59e25c 100644 (file)
@@ -329,6 +329,7 @@ public:
     // helpers for "wxBitmap wxColourScheme::Get()"
     void DrawCheckBitmap(wxDC& dc, const wxRect& rect);
     void DrawUncheckBitmap(wxDC& dc, const wxRect& rect, bool isPressed);
     // helpers for "wxBitmap wxColourScheme::Get()"
     void DrawCheckBitmap(wxDC& dc, const wxRect& rect);
     void DrawUncheckBitmap(wxDC& dc, const wxRect& rect, bool isPressed);
+    void DrawUndeterminedBitmap(wxDC& dc, const wxRect& rect, bool isPressed);
 
 protected:
     // DrawBackground() helpers
 
 protected:
     // DrawBackground() helpers
@@ -469,9 +470,9 @@ private:
           m_penHighlight;
 
     // the checkbox bitmaps: first row is for the normal, second for the
           m_penHighlight;
 
     // the checkbox bitmaps: first row is for the normal, second for the
-    // pressed state and the columns are for checked and unchecked status
-    // respectively
-    wxBitmap m_bitmapsCheckbox[2][2];
+    // pressed state and the columns are for checked, unchecked and
+    // undeterminated respectively
+    wxBitmap m_bitmapsCheckbox[2][3];
 
     // the line wrap bitmap (drawn at the end of wrapped lines)
     wxBitmap m_bmpLineWrap;
 
     // the line wrap bitmap (drawn at the end of wrapped lines)
     wxBitmap m_bmpLineWrap;
@@ -1346,6 +1347,35 @@ void wxGTKRenderer::DrawCheckItem(wxDC& dc,
 // check/radion buttons
 // ----------------------------------------------------------------------------
 
 // check/radion buttons
 // ----------------------------------------------------------------------------
 
+void wxGTKRenderer::DrawUndeterminedBitmap(wxDC& dc,
+                                           const wxRect& rectTotal,
+                                           bool isPressed)
+{
+    // FIXME: For sure it is not GTK look but it is better than nothing.
+    // Show me correct look and I will immediatelly make it better (ABX)
+    wxRect rect = rectTotal;
+
+    wxColour col1, col2;
+
+    if ( isPressed )
+    {
+        col1 = wxSCHEME_COLOUR(m_scheme, SHADOW_DARK);
+        col2 = wxSCHEME_COLOUR(m_scheme, CONTROL_PRESSED);
+    }
+    else
+    {
+        col1 = wxSCHEME_COLOUR(m_scheme, SHADOW_DARK);
+        col2 = wxSCHEME_COLOUR(m_scheme, SHADOW_IN);
+    }
+
+    dc.SetPen(*wxTRANSPARENT_PEN);
+    dc.SetBrush(wxBrush(col1, wxSOLID));
+    dc.DrawRectangle(rect);
+    rect.Deflate(1);
+    dc.SetBrush(wxBrush(col2, wxSOLID));
+    dc.DrawRectangle(rect);
+}
+
 void wxGTKRenderer::DrawUncheckBitmap(wxDC& dc,
                                       const wxRect& rectTotal,
                                       bool isPressed)
 void wxGTKRenderer::DrawUncheckBitmap(wxDC& dc,
                                       const wxRect& rectTotal,
                                       bool isPressed)
@@ -1471,7 +1501,7 @@ wxBitmap wxGTKRenderer::GetCheckBitmap(int flags)
         rect.height = size.y;
         for ( int i = 0; i < 2; i++ )
         {
         rect.height = size.y;
         for ( int i = 0; i < 2; i++ )
         {
-            for ( int j = 0; j < 2; j++ )
+            for ( int j = 0; j < 3; j++ )
                 m_bitmapsCheckbox[i][j].Create(rect.width, rect.height);
         }
 
                 m_bitmapsCheckbox[i][j].Create(rect.width, rect.height);
         }
 
@@ -1485,16 +1515,30 @@ wxBitmap wxGTKRenderer::GetCheckBitmap(int flags)
         dc.SelectObject(m_bitmapsCheckbox[0][1]);
         DrawUncheckBitmap(dc, rect, false);
 
         dc.SelectObject(m_bitmapsCheckbox[0][1]);
         DrawUncheckBitmap(dc, rect, false);
 
+        // normal undeterminated
+        dc.SelectObject(m_bitmapsCheckbox[0][2]);
+        DrawUndeterminedBitmap(dc, rect, false);
+
         // pressed checked
         m_bitmapsCheckbox[1][0] = m_bitmapsCheckbox[0][0];
 
         // pressed unchecked
         dc.SelectObject(m_bitmapsCheckbox[1][1]);
         DrawUncheckBitmap(dc, rect, true);
         // pressed checked
         m_bitmapsCheckbox[1][0] = m_bitmapsCheckbox[0][0];
 
         // pressed unchecked
         dc.SelectObject(m_bitmapsCheckbox[1][1]);
         DrawUncheckBitmap(dc, rect, true);
+
+        // pressed undeterminated
+        dc.SelectObject(m_bitmapsCheckbox[1][2]);
+        DrawUndeterminedBitmap(dc, rect, true);
     }
 
     }
 
-    int row = flags & wxCONTROL_PRESSED ? 1 : 0;
-    int col = flags & wxCONTROL_CHECKED ? 0 : 1;
+    int row = flags & wxCONTROL_PRESSED
+                  ? 1
+                  : 0;
+    int col = flags & wxCONTROL_CHECKED
+                  ? 0
+                  : ( flags & wxCONTROL_UNDETERMINED
+                          ? 2
+                          : 1 );
 
     return m_bitmapsCheckbox[row][col];
 }
 
     return m_bitmapsCheckbox[row][col];
 }
index e5760cca77cb595c37cab6e284bea3696718218d..8ac96094168db47d8c5343a7eaf64238e45b453d 100644 (file)
@@ -110,6 +110,7 @@ enum IndicatorStatus
 {
     IndicatorStatus_Checked,
     IndicatorStatus_Unchecked,
 {
     IndicatorStatus_Checked,
     IndicatorStatus_Unchecked,
+    IndicatorStatus_Undeterminated,
     IndicatorStatus_Max
 };
 
     IndicatorStatus_Max
 };
 
@@ -1009,6 +1010,54 @@ static const char *unchecked_item_xpm[] = {
 "wwwwwwwwwwwww"
 };
 
 "wwwwwwwwwwwww"
 };
 
+static const char *undetermined_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"13 13 5 1",
+"A c #030303",
+"B c #838383",
+"C c #C3C3C3",
+"D c #FBFBFB",
+"E c #DBDBDB",
+/* pixels */
+"BBBBBBBBBBBBD",
+"BAAAAAAAAAAED",
+"BACDCDCDCDCED",
+"BADCDCDCDBDED",
+"BACDCDCDBBCED",
+"BADBDCEBBBDED",
+"BACBBDBBBDCED",
+"BADBBBBBDCDED",
+"BACDBBBDCDCED",
+"BADCDBDCDCDED",
+"BACDCDCDCDCED",
+"BEEEEEEEEEEED",
+"DDDDDDDDDDDDD"
+};
+
+static const char *pressed_undetermined_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"13 13 5 1",
+"A c #040404",
+"B c #848484",
+"C c #C4C4C4",
+"D c #FCFCFC",
+"E c #DCDCDC",
+/* pixels */
+"BBBBBBBBBBBBD",
+"BAAAAAAAAAAED",
+"BACCCCCCCCCCD",
+"BACCCCCCCACED",
+"BACCCCCCAACED",
+"BACACCCAAACED",
+"BACAACAAACCED",
+"BACAAAAACCCED",
+"BACCAAACCCCCD",
+"BACCCACCCCCED",
+"BACCCCCCCCCED",
+"BEEEEEEEEEEED",
+"DDDDDDDDDDDDD"
+};
+
 static const char *checked_radio_xpm[] = {
 /* columns rows colors chars-per-pixel */
 "12 12 6 1",
 static const char *checked_radio_xpm[] = {
 /* columns rows colors chars-per-pixel */
 "12 12 6 1",
@@ -1135,40 +1184,40 @@ static const char **
     // checkboxes first
     {
         // normal state
     // checkboxes first
     {
         // normal state
-        { checked_xpm, unchecked_xpm },
+        { checked_xpm, unchecked_xpm, undetermined_xpm },
 
         // pressed state
 
         // pressed state
-        { pressed_checked_xpm, pressed_unchecked_xpm },
+        { pressed_checked_xpm, pressed_unchecked_xpm, pressed_undetermined_xpm },
 
         // disabled state
 
         // disabled state
-        { pressed_disabled_checked_xpm, pressed_unchecked_xpm },
+        { pressed_disabled_checked_xpm, pressed_unchecked_xpm, pressed_disabled_checked_xpm },
     },
 
     // radio
     {
         // normal state
     },
 
     // radio
     {
         // normal state
-        { checked_radio_xpm, unchecked_radio_xpm },
+        { checked_radio_xpm, unchecked_radio_xpm, NULL },
 
         // pressed state
 
         // pressed state
-        { pressed_checked_radio_xpm, pressed_unchecked_radio_xpm },
+        { pressed_checked_radio_xpm, pressed_unchecked_radio_xpm, NULL },
 
         // disabled state
 
         // disabled state
-        { pressed_disabled_checked_radio_xpm, pressed_unchecked_radio_xpm },
+        { pressed_disabled_checked_radio_xpm, pressed_unchecked_radio_xpm, NULL },
     },
 
     // menu
     {
         // normal state
     },
 
     // menu
     {
         // normal state
-        { checked_menu_xpm, NULL },
+        { checked_menu_xpm, NULL, NULL },
 
         // selected state
 
         // selected state
-        { selected_checked_menu_xpm, NULL },
+        { selected_checked_menu_xpm, NULL, NULL },
 
         // disabled state
 
         // disabled state
-        { disabled_checked_menu_xpm, NULL },
+        { disabled_checked_menu_xpm, NULL, NULL },
 
         // disabled selected state
 
         // disabled selected state
-        { selected_disabled_checked_menu_xpm, NULL },
+        { selected_disabled_checked_menu_xpm, NULL, NULL },
     }
 };
 
     }
 };
 
@@ -2315,7 +2364,9 @@ wxBitmap wxWin32Renderer::GetIndicator(IndicatorType indType, int flags)
 
     IndicatorStatus indStatus = flags & wxCONTROL_CHECKED
                                     ? IndicatorStatus_Checked
 
     IndicatorStatus indStatus = flags & wxCONTROL_CHECKED
                                     ? IndicatorStatus_Checked
-                                    : IndicatorStatus_Unchecked;
+                                    : ( flags & wxCONTROL_UNDETERMINED
+                                          ? IndicatorStatus_Undeterminated
+                                          : IndicatorStatus_Unchecked );
 
     wxBitmap bmp = m_bmpIndicators[indType][indState][indStatus];
     if ( !bmp.Ok() )
 
     wxBitmap bmp = m_bmpIndicators[indType][indState][indStatus];
     if ( !bmp.Ok() )