3rd state in checkboxes for wxUniv [closes bug#1040585].

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@30603 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Włodzimierz Skiba
2004-11-18 13:16:41 +00:00
parent 6ff734acec
commit 415a0ff16d
6 changed files with 190 additions and 37 deletions

View File

@@ -263,6 +263,7 @@ wxUniv:
- wxBU_... button align flags support - wxBU_... button align flags support
- vertical notebook orientation support - vertical notebook orientation support
- 3rd state support for checkboxes
2.5.3 2.5.3

View File

@@ -54,6 +54,7 @@ enum
wxCONTROL_SELECTED = 0x00000020, // selected item in e.g. listbox wxCONTROL_SELECTED = 0x00000020, // selected item in e.g. listbox
wxCONTROL_CHECKED = 0x00000040, // (check/radio button) is checked wxCONTROL_CHECKED = 0x00000040, // (check/radio button) is checked
wxCONTROL_CHECKABLE = 0x00000080, // (menu) item can be checked wxCONTROL_CHECKABLE = 0x00000080, // (menu) item can be checked
wxCONTROL_UNDETERMINED = wxCONTROL_CHECKABLE, // (check) undetermined state
wxCONTROL_FLAGS_MASK = 0x000000ff, wxCONTROL_FLAGS_MASK = 0x000000ff,

View File

@@ -54,7 +54,7 @@ public:
{ {
Status_Checked, Status_Checked,
Status_Unchecked, Status_Unchecked,
Status_Unknown, Status_3rdState,
Status_Max Status_Max
}; };
@@ -102,8 +102,11 @@ public:
virtual bool IsPressed() const { return m_isPressed; } virtual bool IsPressed() const { return m_isPressed; }
virtual bool HasTransparentBackground() { return true; } virtual bool HasTransparentBackground() { return true; }
protected: protected:
virtual void DoSet3StateValue(wxCheckBoxState WXUNUSED(state));
virtual wxCheckBoxState DoGet3StateValue() const;
virtual bool PerformAction(const wxControlAction& action, virtual bool PerformAction(const wxControlAction& action,
long numArg = -1, long numArg = -1,
const wxString& strArg = wxEmptyString); const wxString& strArg = wxEmptyString);

View 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; Set3StateValue( value ? wxCHK_CHECKED : wxCHK_UNCHECKED );
if ( status != m_status )
{
m_status = status;
if ( m_status == Status_Checked )
{
// invoke the hook
OnCheck();
}
Refresh();
}
} }
void wxCheckBox::OnCheck() void wxCheckBox::OnCheck()
@@ -151,8 +139,11 @@ void wxCheckBox::DoDraw(wxControlRenderer *renderer)
dc.SetFont(GetFont()); dc.SetFont(GetFont());
dc.SetTextForeground(GetForegroundColour()); dc.SetTextForeground(GetForegroundColour());
if ( m_status == Status_Checked ) switch ( Get3StateValue() )
flags |= wxCONTROL_CHECKED; {
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() void wxCheckBox::Press()
{ {
if ( !m_isPressed ) 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()); wxCommandEvent event(wxEVT_COMMAND_CHECKBOX_CLICKED, GetId());
InitCommandEvent(event); 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);
} }

View File

@@ -329,6 +329,7 @@ public:
// helpers for "wxBitmap wxColourScheme::Get()" // helpers for "wxBitmap wxColourScheme::Get()"
void DrawCheckBitmap(wxDC& dc, const wxRect& rect); void DrawCheckBitmap(wxDC& dc, const wxRect& rect);
void DrawUncheckBitmap(wxDC& dc, const wxRect& rect, bool isPressed); void DrawUncheckBitmap(wxDC& dc, const wxRect& rect, bool isPressed);
void DrawUndeterminedBitmap(wxDC& dc, const wxRect& rect, bool isPressed);
protected: protected:
// DrawBackground() helpers // DrawBackground() helpers
@@ -469,9 +470,9 @@ private:
m_penHighlight; m_penHighlight;
// the checkbox bitmaps: first row is for the normal, second for the // the checkbox bitmaps: first row is for the normal, second for the
// pressed state and the columns are for checked and unchecked status // pressed state and the columns are for checked, unchecked and
// respectively // undeterminated respectively
wxBitmap m_bitmapsCheckbox[2][2]; wxBitmap m_bitmapsCheckbox[2][3];
// the line wrap bitmap (drawn at the end of wrapped lines) // the line wrap bitmap (drawn at the end of wrapped lines)
wxBitmap m_bmpLineWrap; 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, void wxGTKRenderer::DrawUncheckBitmap(wxDC& dc,
const wxRect& rectTotal, const wxRect& rectTotal,
bool isPressed) bool isPressed)
@@ -1471,7 +1501,7 @@ wxBitmap wxGTKRenderer::GetCheckBitmap(int flags)
rect.height = size.y; rect.height = size.y;
for ( int i = 0; i < 2; i++ ) 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]); dc.SelectObject(m_bitmapsCheckbox[0][1]);
DrawUncheckBitmap(dc, rect, false); DrawUncheckBitmap(dc, rect, false);
// normal undeterminated
dc.SelectObject(m_bitmapsCheckbox[0][2]);
DrawUndeterminedBitmap(dc, rect, false);
// pressed checked // pressed checked
m_bitmapsCheckbox[1][0] = m_bitmapsCheckbox[0][0]; m_bitmapsCheckbox[1][0] = m_bitmapsCheckbox[0][0];
// pressed unchecked // pressed unchecked
dc.SelectObject(m_bitmapsCheckbox[1][1]); dc.SelectObject(m_bitmapsCheckbox[1][1]);
DrawUncheckBitmap(dc, rect, true); DrawUncheckBitmap(dc, rect, true);
// pressed undeterminated
dc.SelectObject(m_bitmapsCheckbox[1][2]);
DrawUndeterminedBitmap(dc, rect, true);
} }
int row = flags & wxCONTROL_PRESSED ? 1 : 0; int row = flags & wxCONTROL_PRESSED
int col = flags & wxCONTROL_CHECKED ? 0 : 1; ? 1
: 0;
int col = flags & wxCONTROL_CHECKED
? 0
: ( flags & wxCONTROL_UNDETERMINED
? 2
: 1 );
return m_bitmapsCheckbox[row][col]; return m_bitmapsCheckbox[row][col];
} }

View File

@@ -110,6 +110,7 @@ enum IndicatorStatus
{ {
IndicatorStatus_Checked, IndicatorStatus_Checked,
IndicatorStatus_Unchecked, 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[] = { static const char *checked_radio_xpm[] = {
/* columns rows colors chars-per-pixel */ /* columns rows colors chars-per-pixel */
"12 12 6 1", "12 12 6 1",
@@ -1135,40 +1184,40 @@ static const char **
// checkboxes first // checkboxes first
{ {
// normal state // 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 // radio
{ {
// normal state // 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 // menu
{ {
// normal state // 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 indStatus = flags & wxCONTROL_CHECKED
? IndicatorStatus_Checked ? IndicatorStatus_Checked
: IndicatorStatus_Unchecked; : ( flags & wxCONTROL_UNDETERMINED
? IndicatorStatus_Undeterminated
: IndicatorStatus_Unchecked );
wxBitmap bmp = m_bmpIndicators[indType][indState][indStatus]; wxBitmap bmp = m_bmpIndicators[indType][indState][indStatus];
if ( !bmp.Ok() ) if ( !bmp.Ok() )