diff --git a/include/wx/generic/private/grid.h b/include/wx/generic/private/grid.h index c67f462902..d0c01a16af 100644 --- a/include/wx/generic/private/grid.h +++ b/include/wx/generic/private/grid.h @@ -1007,5 +1007,12 @@ private: wxGridDataTypeInfoArray m_typeinfo; }; +// Returns the rect of the check box in a cell with the given alignmens +// and the size. +// The function is used by wxGridCellBoolEditor and wxGridCellBoolRenderer. +wxRect wxGetGridCheckBoxRect(const wxSize& checkBoxSize, + const wxRect& cellRect, + int hAlign, int vAlign); + #endif // wxUSE_GRID #endif // _WX_GENERIC_GRID_PRIVATE_H_ diff --git a/src/generic/grid.cpp b/src/generic/grid.cpp index f940fbbd40..2648f750a9 100644 --- a/src/generic/grid.cpp +++ b/src/generic/grid.cpp @@ -111,6 +111,9 @@ const int GRID_HASH_SIZE = 100; // operation const int DRAG_SENSITIVITY = 3; +// the space between the cell edge and the checkbox mark +const int GRID_CELL_CHECKBOX_MARGIN_X = 2; + } // anonymous namespace #include "wx/arrimpl.cpp" @@ -6980,18 +6983,10 @@ void wxGrid::ShowCellEditControl() if (rect.x < 0) nXMove = rect.x; -#ifndef __WXQT__ - // cell is shifted by one pixel - // However, don't allow x or y to become negative - // since the SetSize() method interprets that as - // "don't change." - if (rect.x > 0) - rect.x--; - if (rect.y > 0) - rect.y--; -#else +#ifdef __WXQT__ // Substract 1 pixel in every dimension to fit in the cell area. // If not, Qt will draw the control outside the cell. + // TODO: Check offsets under Qt. rect.Deflate(1, 1); #endif @@ -10337,4 +10332,44 @@ wxGridCellEditor* wxGridTypeRegistry::GetEditor(int index) return editor; } +wxRect wxGetGridCheckBoxRect(const wxSize& checkBoxSize, + const wxRect& cellRect, + int hAlign, int WXUNUSED(vAlign)) +{ + // TODO: support vAlign + + wxRect checkBoxRect; + checkBoxRect.SetY(cellRect.y + cellRect.height / 2 - checkBoxSize.y / 2); + + wxCoord minSize = wxMin(cellRect.width, cellRect.height); + if ( checkBoxRect.GetWidth() >= minSize || checkBoxRect.GetHeight() >= minSize ) + { + // let the checkbox mark be even smaller than the min size + // to leave some space between cell edges and the checkbox + const int newSize = wxMax(1, minSize - 2); + checkBoxRect.SetWidth(newSize); + checkBoxRect.SetHeight(newSize); + } + else + { + checkBoxRect.SetSize(checkBoxSize); + } + + if ( hAlign & wxALIGN_CENTER_HORIZONTAL ) + { + checkBoxRect.SetX(cellRect.x + cellRect.width / 2 - checkBoxSize.x / 2); + } + else if ( hAlign & wxALIGN_RIGHT ) + { + checkBoxRect.SetX(cellRect.x + cellRect.width + - checkBoxSize.x - GRID_CELL_CHECKBOX_MARGIN_X); + } + else // ( hAlign == wxALIGN_LEFT ) and invalid alignment value + { + checkBoxRect.SetX(cellRect.x + GRID_CELL_CHECKBOX_MARGIN_X); + } + + return checkBoxRect; +} + #endif // wxUSE_GRID diff --git a/src/generic/gridctrl.cpp b/src/generic/gridctrl.cpp index f6df548502..a72c4b1674 100644 --- a/src/generic/gridctrl.cpp +++ b/src/generic/gridctrl.cpp @@ -31,6 +31,7 @@ #include "wx/tokenzr.h" #include "wx/renderer.h" +#include "wx/generic/private/grid.h" // ---------------------------------------------------------------------------- // wxGridCellRenderer @@ -936,7 +937,8 @@ wxSize wxGridCellBoolRenderer::GetBestSize(wxGrid& grid, // compute it only once (no locks for MT safeness in GUI thread...) if ( !ms_sizeCheckMark.x ) { - ms_sizeCheckMark = wxRendererNative::Get().GetCheckBoxSize(&grid); + ms_sizeCheckMark = + wxRendererNative::Get().GetCheckBoxSize(&grid, wxCONTROL_CELL); } return ms_sizeCheckMark; @@ -951,43 +953,16 @@ void wxGridCellBoolRenderer::Draw(wxGrid& grid, { wxGridCellRenderer::Draw(grid, attr, dc, rect, row, col, isSelected); - // draw a check mark in the centre (ignoring alignment - TODO) - wxSize size = GetBestSize(grid, attr, dc, row, col); - - // don't draw outside the cell - wxCoord minSize = wxMin(rect.width, rect.height); - if ( size.x >= minSize || size.y >= minSize ) - { - // and even leave (at least) 1 pixel margin - size.x = size.y = minSize; - } - - // draw a border around checkmark int vAlign, hAlign; attr.GetAlignment(&hAlign, &vAlign); - wxRect rectBorder; - if (hAlign == wxALIGN_CENTRE) - { - rectBorder.x = rect.x + rect.width / 2 - size.x / 2; - rectBorder.y = rect.y + rect.height / 2 - size.y / 2; - rectBorder.width = size.x; - rectBorder.height = size.y; - } - else if (hAlign == wxALIGN_LEFT) - { - rectBorder.x = rect.x + 2; - rectBorder.y = rect.y + rect.height / 2 - size.y / 2; - rectBorder.width = size.x; - rectBorder.height = size.y; - } - else if (hAlign == wxALIGN_RIGHT) - { - rectBorder.x = rect.x + rect.width - size.x - 2; - rectBorder.y = rect.y + rect.height / 2 - size.y / 2; - rectBorder.width = size.x; - rectBorder.height = size.y; - } + const wxRect + checkBoxRect = wxGetGridCheckBoxRect + ( + GetBestSize(grid, attr, dc, row, col), + rect, + hAlign, vAlign + ); bool value; if ( grid.GetTable()->CanGetValueAs(row, col, wxGRID_VALUE_BOOL) ) @@ -1000,11 +975,11 @@ void wxGridCellBoolRenderer::Draw(wxGrid& grid, value = wxGridCellBoolEditor::IsTrueValue(cellval); } - int flags = 0; + int flags = wxCONTROL_CELL; if (value) flags |= wxCONTROL_CHECKED; - wxRendererNative::Get().DrawCheckBox( &grid, dc, rectBorder, flags ); + wxRendererNative::Get().DrawCheckBox( &grid, dc, checkBoxRect, flags ); } #endif // wxUSE_GRID diff --git a/src/generic/grideditors.cpp b/src/generic/grideditors.cpp index e5b008697b..08954cc7fe 100644 --- a/src/generic/grideditors.cpp +++ b/src/generic/grideditors.cpp @@ -440,38 +440,17 @@ void wxGridCellTextEditor::SetSize(const wxRect& rectOrig) // Make the edit control large enough to allow for internal margins // - // TODO: remove this if the text ctrl sizing is improved esp. for unix + // TODO: remove this if the text ctrl sizing is improved // -#if defined(__WXGTK__) - if (rect.x != 0) - { - rect.x += 1; - rect.y += 1; - rect.width -= 1; - rect.height -= 1; - } -#elif defined(__WXMSW__) - if ( rect.x == 0 ) - rect.x += 2; - else - rect.x += 3; - - if ( rect.y == 0 ) - rect.y += 2; - else - rect.y += 3; +#if defined(__WXMSW__) + rect.x += 2; + rect.y += 2; rect.width -= 2; rect.height -= 2; -#elif defined(__WXOSX__) - rect.x += 1; - rect.y += 1; - - rect.width -= 1; - rect.height -= 1; -#else - int extra_x = ( rect.x > 2 ) ? 2 : 1; - int extra_y = ( rect.y > 2 ) ? 2 : 1; +#elif !defined(__WXGTK__) + int extra_x = 2; + int extra_y = 2; #if defined(__WXMOTIF__) extra_x *= 2; @@ -1239,73 +1218,28 @@ void wxGridCellBoolEditor::Create(wxWindow* parent, void wxGridCellBoolEditor::SetSize(const wxRect& r) { - bool resize = false; - wxSize size = m_control->GetSize(); - wxCoord minSize = wxMin(r.width, r.height); - - // check if the checkbox is not too big/small for this cell - wxSize sizeBest = m_control->GetBestSize(); - if ( !(size == sizeBest) ) - { - // reset to default size if it had been made smaller - size = sizeBest; - - resize = true; - } - - if ( size.x >= minSize || size.y >= minSize ) - { - // leave 1 pixel margin - size.x = size.y = minSize - 2; - - resize = true; - } - - if ( resize ) - { - m_control->SetSize(size); - } - - // position it in the centre of the rectangle (TODO: support alignment?) - -#if defined(__WXGTK__) || defined (__WXMOTIF__) - // the checkbox without label still has some space to the right in wxGTK, - // so shift it to the right - size.x -= 8; -#elif defined(__WXMSW__) - // here too, but in other way - size.x += 1; - size.y -= 2; -#endif - int hAlign = wxALIGN_CENTRE; int vAlign = wxALIGN_CENTRE; if (GetCellAttr()) GetCellAttr()->GetAlignment(& hAlign, & vAlign); - int x = 0, y = 0; - if (hAlign == wxALIGN_LEFT) - { - x = r.x + 2; + const wxRect + checkBoxRect = wxGetGridCheckBoxRect + ( + wxRendererNative::Get(). + GetCheckBoxSize(GetWindow(), wxCONTROL_CELL), + r, + hAlign, vAlign + ); -#ifdef __WXMSW__ - x += 2; -#endif - - y = r.y + r.height / 2 - size.y / 2; - } - else if (hAlign == wxALIGN_RIGHT) + // resize the control if required + if ( m_control->GetSize() != checkBoxRect.GetSize() ) { - x = r.x + r.width - size.x - 2; - y = r.y + r.height / 2 - size.y / 2; - } - else if (hAlign == wxALIGN_CENTRE) - { - x = r.x + r.width / 2 - size.x / 2; - y = r.y + r.height / 2 - size.y / 2; + m_control->SetSize(checkBoxRect.GetSize()); } - m_control->Move(x, y); + // and move it + m_control->Move(checkBoxRect.GetPosition()); } void wxGridCellBoolEditor::Show(bool show, wxGridCellAttr *attr)