- wxBU_... button align flags support
- vertical notebook orientation support
+- 3rd state support for checkboxes
2.5.3
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,
{
Status_Checked,
Status_Unchecked,
- Status_Unknown,
+ Status_3rdState,
Status_Max
};
virtual bool IsPressed() const { return m_isPressed; }
virtual bool HasTransparentBackground() { return true; }
-
+
protected:
+ virtual void DoSet3StateValue(wxCheckBoxState WXUNUSED(state));
+ virtual wxCheckBoxState DoGet3StateValue() const;
+
virtual bool PerformAction(const wxControlAction& action,
long numArg = -1,
const wxString& strArg = wxEmptyString);
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()
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));
// 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 )
{
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)
{
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);
}
// 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
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;
// 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)
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);
}
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 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];
}
{
IndicatorStatus_Checked,
IndicatorStatus_Unchecked,
+ IndicatorStatus_Undeterminated,
IndicatorStatus_Max
};
"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",
// checkboxes first
{
// normal state
- { checked_xpm, unchecked_xpm },
+ { checked_xpm, unchecked_xpm, undetermined_xpm },
// pressed state
- { pressed_checked_xpm, pressed_unchecked_xpm },
+ { pressed_checked_xpm, pressed_unchecked_xpm, pressed_undetermined_xpm },
// disabled state
- { pressed_disabled_checked_xpm, pressed_unchecked_xpm },
+ { pressed_disabled_checked_xpm, pressed_unchecked_xpm, pressed_disabled_checked_xpm },
},
// radio
{
// normal state
- { checked_radio_xpm, unchecked_radio_xpm },
+ { checked_radio_xpm, unchecked_radio_xpm, NULL },
// pressed state
- { pressed_checked_radio_xpm, pressed_unchecked_radio_xpm },
+ { pressed_checked_radio_xpm, pressed_unchecked_radio_xpm, NULL },
// disabled state
- { pressed_disabled_checked_radio_xpm, pressed_unchecked_radio_xpm },
+ { pressed_disabled_checked_radio_xpm, pressed_unchecked_radio_xpm, NULL },
},
// menu
{
// normal state
- { checked_menu_xpm, NULL },
+ { checked_menu_xpm, NULL, NULL },
// selected state
- { selected_checked_menu_xpm, NULL },
+ { selected_checked_menu_xpm, NULL, NULL },
// disabled state
- { disabled_checked_menu_xpm, NULL },
+ { disabled_checked_menu_xpm, NULL, NULL },
// disabled selected state
- { selected_disabled_checked_menu_xpm, NULL },
+ { selected_disabled_checked_menu_xpm, NULL, NULL },
}
};
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() )