Improve calculating wxSimpleCheckBox rectangle

The code to calculate rectangle occupied by the check box is moved to the shared function GetBoxRect().
Check box rectangle is stored in the data member and this cached position and size are used in the drawing operations and hit tests.
This commit is contained in:
Artur Wieczorek
2019-01-20 18:21:29 +01:00
parent 5261605a61
commit 4c9684f8d1

View File

@@ -1424,13 +1424,9 @@ enum
const int wxSCB_SETVALUE_CYCLE = 2; const int wxSCB_SETVALUE_CYCLE = 2;
static void DrawSimpleCheckBox( wxWindow* win, wxDC& dc, const wxRect& rect, static void DrawSimpleCheckBox(wxWindow* win, wxDC& dc, const wxRect& rect, int state)
int box_h, int state )
{ {
#if wxPG_USE_RENDERER_NATIVE #if wxPG_USE_RENDERER_NATIVE
// Box rectangle
wxRect r(rect.x+wxPG_XBEFORETEXT, rect.y+((rect.height-box_h)/2),
box_h, box_h);
int cbFlags = 0; int cbFlags = 0;
if ( state & wxSCB_STATE_UNSPECIFIED ) if ( state & wxSCB_STATE_UNSPECIFIED )
@@ -1454,13 +1450,10 @@ static void DrawSimpleCheckBox( wxWindow* win, wxDC& dc, const wxRect& rect,
#endif #endif
} }
wxRendererNative::Get().DrawCheckBox(win, dc, r, cbFlags); wxRendererNative::Get().DrawCheckBox(win, dc, rect, cbFlags);
#else #else
wxUnusedVar(win); wxUnusedVar(win);
// Box rectangle
wxRect r(rect.x+wxPG_XBEFORETEXT, rect.y+((rect.height-box_h)/2),
box_h, box_h);
wxColour useCol = dc.GetTextForeground(); wxColour useCol = dc.GetTextForeground();
if ( state & wxSCB_STATE_UNSPECIFIED ) if ( state & wxSCB_STATE_UNSPECIFIED )
@@ -1468,6 +1461,7 @@ static void DrawSimpleCheckBox( wxWindow* win, wxDC& dc, const wxRect& rect,
useCol = wxColour(220, 220, 220); useCol = wxColour(220, 220, 220);
} }
wxRect r(rect);
// Draw check mark first because it is likely to overdraw the // Draw check mark first because it is likely to overdraw the
// surrounding rectangle. // surrounding rectangle.
if ( state & wxSCB_STATE_CHECKED ) if ( state & wxSCB_STATE_CHECKED )
@@ -1529,15 +1523,29 @@ public:
SetFont( parent->GetFont() ); SetFont( parent->GetFont() );
m_state = 0; m_state = 0;
m_boxHeight = 12; SetBoxHeight(12);
SetBackgroundStyle( wxBG_STYLE_PAINT ); SetBackgroundStyle( wxBG_STYLE_PAINT );
} }
virtual ~wxSimpleCheckBox(); virtual ~wxSimpleCheckBox();
void SetBoxHeight(int height)
{
m_boxHeight = height;
// Box rectangle
wxRect rect(GetClientSize());
rect.y += 1;
rect.width += 1;
m_boxRect = GetBoxRect(rect, m_boxHeight);
}
static wxRect GetBoxRect(const wxRect& r, int box_h)
{
return wxRect(r.x + wxPG_XBEFORETEXT, r.y + ((r.height - box_h) / 2), box_h, box_h);
}
int m_state; int m_state;
int m_boxHeight;
private: private:
void OnPaint( wxPaintEvent& event ); void OnPaint( wxPaintEvent& event );
@@ -1546,11 +1554,15 @@ private:
void OnResize( wxSizeEvent& event ) void OnResize( wxSizeEvent& event )
{ {
SetBoxHeight(m_boxHeight); // Recalculate box rectangle
Refresh(); Refresh();
event.Skip(); event.Skip();
} }
void OnLeftClickActivate( wxCommandEvent& evt ); void OnLeftClickActivate( wxCommandEvent& evt );
int m_boxHeight;
wxRect m_boxRect;
wxDECLARE_EVENT_TABLE(); wxDECLARE_EVENT_TABLE();
}; };
@@ -1571,17 +1583,13 @@ wxSimpleCheckBox::~wxSimpleCheckBox()
void wxSimpleCheckBox::OnPaint( wxPaintEvent& WXUNUSED(event) ) void wxSimpleCheckBox::OnPaint( wxPaintEvent& WXUNUSED(event) )
{ {
wxRect rect(GetClientSize());
wxAutoBufferedPaintDC dc(this); wxAutoBufferedPaintDC dc(this);
dc.Clear();
rect.y += 1;
rect.width += 1;
wxColour bgcol = GetBackgroundColour(); wxColour bgcol = GetBackgroundColour();
dc.SetBackground(wxBrush(bgcol));
dc.Clear();
dc.SetBrush( bgcol ); dc.SetBrush( bgcol );
dc.SetPen( bgcol ); dc.SetPen( bgcol );
dc.DrawRectangle( rect );
dc.SetTextForeground(GetForegroundColour()); dc.SetTextForeground(GetForegroundColour());
@@ -1590,13 +1598,12 @@ void wxSimpleCheckBox::OnPaint( wxPaintEvent& WXUNUSED(event) )
GetFont().GetWeight() == wxFONTWEIGHT_BOLD ) GetFont().GetWeight() == wxFONTWEIGHT_BOLD )
state |= wxSCB_STATE_BOLD; state |= wxSCB_STATE_BOLD;
DrawSimpleCheckBox(this, dc, rect, m_boxHeight, state); DrawSimpleCheckBox(this, dc, m_boxRect, state);
} }
void wxSimpleCheckBox::OnLeftClick( wxMouseEvent& event ) void wxSimpleCheckBox::OnLeftClick( wxMouseEvent& event )
{ {
if ( (event.m_x > (wxPG_XBEFORETEXT-2)) && if ( m_boxRect.Contains(event.GetPosition()) )
(event.m_x <= (wxPG_XBEFORETEXT-2+m_boxHeight)) )
{ {
SetValue(wxSCB_SETVALUE_CYCLE); SetValue(wxSCB_SETVALUE_CYCLE);
} }
@@ -1631,11 +1638,11 @@ void wxSimpleCheckBox::SetValue( int value )
void wxSimpleCheckBox::OnLeftClickActivate( wxCommandEvent& evt ) void wxSimpleCheckBox::OnLeftClickActivate( wxCommandEvent& evt )
{ {
// Construct mouse pseudo-event for initial mouse click wxPoint pt(evt.GetInt(), evt.GetExtraLong());
wxMouseEvent mouseEvt(wxEVT_LEFT_DOWN); if ( m_boxRect.Contains(pt) )
mouseEvt.m_x = evt.GetInt(); {
mouseEvt.m_y = evt.GetExtraLong(); SetValue(wxSCB_SETVALUE_CYCLE);
OnLeftClick(mouseEvt); }
} }
wxPGWindowList wxPGCheckBoxEditor::CreateControls( wxPropertyGrid* propGrid, wxPGWindowList wxPGCheckBoxEditor::CreateControls( wxPropertyGrid* propGrid,
@@ -1694,7 +1701,9 @@ void wxPGCheckBoxEditor::DrawValue( wxDC& dc, const wxRect& rect,
state |= wxSCB_STATE_UNSPECIFIED; state |= wxSCB_STATE_UNSPECIFIED;
} }
DrawSimpleCheckBox(property->GetGrid(), dc, rect, dc.GetCharHeight(), state); // Box rectangle
wxRect r = wxSimpleCheckBox::GetBoxRect(rect, dc.GetCharHeight());
DrawSimpleCheckBox(property->GetGrid(), dc, r, state);
} }
void wxPGCheckBoxEditor::UpdateControl( wxPGProperty* property, void wxPGCheckBoxEditor::UpdateControl( wxPGProperty* property,
@@ -1709,7 +1718,7 @@ void wxPGCheckBoxEditor::UpdateControl( wxPGProperty* property,
cb->m_state = wxSCB_STATE_UNSPECIFIED; cb->m_state = wxSCB_STATE_UNSPECIFIED;
wxPropertyGrid* propGrid = property->GetGrid(); wxPropertyGrid* propGrid = property->GetGrid();
cb->m_boxHeight = propGrid->GetFontHeight(); cb->SetBoxHeight(propGrid->GetFontHeight());
cb->Refresh(); cb->Refresh();
} }