Significant check box editor refactoring, including fix to UpdateControl() not doing its job correctly if property value was unspecified. Also, unspecified value is now drawn as a faint rectangle
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@57827 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -1187,17 +1187,34 @@ WX_PG_IMPLEMENT_INTERNAL_EDITOR_CLASS(CheckBox,
|
|||||||
wxPGEditor)
|
wxPGEditor)
|
||||||
|
|
||||||
|
|
||||||
// state argument: 0x01 = set if checked
|
// Check box state flags
|
||||||
// 0x02 = set if rectangle should be bold
|
enum
|
||||||
static void DrawSimpleCheckBox( wxDC& dc, const wxRect& rect, int box_hei, int state, const wxColour& linecol )
|
|
||||||
{
|
{
|
||||||
|
wxSCB_STATE_UNCHECKED = 0,
|
||||||
|
wxSCB_STATE_CHECKED = 1,
|
||||||
|
wxSCB_STATE_BOLD = 2,
|
||||||
|
wxSCB_STATE_UNSPECIFIED = 4
|
||||||
|
};
|
||||||
|
|
||||||
|
const int wxSCB_SETVALUE_CYCLE = 2;
|
||||||
|
|
||||||
|
|
||||||
|
static void DrawSimpleCheckBox( wxDC& dc, const wxRect& rect, int box_hei,
|
||||||
|
int state, const wxColour& lineCol )
|
||||||
|
{
|
||||||
// Box rectangle.
|
// Box rectangle.
|
||||||
wxRect r(rect.x+wxPG_XBEFORETEXT,rect.y+((rect.height-box_hei)/2),box_hei,box_hei);
|
wxRect r(rect.x+wxPG_XBEFORETEXT,rect.y+((rect.height-box_hei)/2),
|
||||||
|
box_hei,box_hei);
|
||||||
|
wxColour useCol = lineCol;
|
||||||
|
|
||||||
|
if ( state & wxSCB_STATE_UNSPECIFIED )
|
||||||
|
{
|
||||||
|
useCol = wxColour(220, 220, 220);
|
||||||
|
}
|
||||||
|
|
||||||
// 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 & 1 )
|
if ( state & wxSCB_STATE_CHECKED )
|
||||||
{
|
{
|
||||||
wxRect r2(r.x+wxPG_CHECKMARK_XADJ,
|
wxRect r2(r.x+wxPG_CHECKMARK_XADJ,
|
||||||
r.y+wxPG_CHECKMARK_YADJ,
|
r.y+wxPG_CHECKMARK_YADJ,
|
||||||
@@ -1211,18 +1228,17 @@ static void DrawSimpleCheckBox( wxDC& dc, const wxRect& rect, int box_hei, int s
|
|||||||
// This would draw a simple cross check mark.
|
// This would draw a simple cross check mark.
|
||||||
// dc.DrawLine(r.x,r.y,r.x+r.width-1,r.y+r.height-1);
|
// dc.DrawLine(r.x,r.y,r.x+r.width-1,r.y+r.height-1);
|
||||||
// dc.DrawLine(r.x,r.y+r.height-1,r.x+r.width-1,r.y);
|
// dc.DrawLine(r.x,r.y+r.height-1,r.x+r.width-1,r.y);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !(state & 2) )
|
if ( !(state & wxSCB_STATE_BOLD) )
|
||||||
{
|
{
|
||||||
// Pen for thin rectangle.
|
// Pen for thin rectangle.
|
||||||
dc.SetPen(linecol);
|
dc.SetPen(useCol);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Pen for bold rectangle.
|
// Pen for bold rectangle.
|
||||||
wxPen linepen(linecol,2,wxSOLID);
|
wxPen linepen(useCol,2,wxSOLID);
|
||||||
linepen.SetJoin(wxJOIN_MITER); // This prevents round edges.
|
linepen.SetJoin(wxJOIN_MITER); // This prevents round edges.
|
||||||
dc.SetPen(linepen);
|
dc.SetPen(linepen);
|
||||||
r.x++;
|
r.x++;
|
||||||
@@ -1256,39 +1272,98 @@ public:
|
|||||||
SetFont( parent->GetFont() );
|
SetFont( parent->GetFont() );
|
||||||
|
|
||||||
m_state = 0;
|
m_state = 0;
|
||||||
wxPropertyGrid* pg = (wxPropertyGrid*) parent->GetParent();
|
m_boxHeight = 12;
|
||||||
wxASSERT( pg->IsKindOf(CLASSINFO(wxPropertyGrid)) );
|
|
||||||
m_boxHeight = pg->GetFontHeight();
|
SetBackgroundStyle( wxBG_STYLE_CUSTOM );
|
||||||
SetBackgroundStyle( wxBG_STYLE_COLOUR );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~wxSimpleCheckBox();
|
virtual ~wxSimpleCheckBox();
|
||||||
|
|
||||||
virtual bool ProcessEvent(wxEvent& event);
|
|
||||||
|
|
||||||
int m_state;
|
int m_state;
|
||||||
int m_boxHeight;
|
int m_boxHeight;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void OnPaint( wxPaintEvent& event );
|
||||||
|
void OnLeftClick( wxMouseEvent& event );
|
||||||
|
void OnKeyDown( wxKeyEvent& event );
|
||||||
|
|
||||||
|
void OnResize( wxSizeEvent& event )
|
||||||
|
{
|
||||||
|
Refresh();
|
||||||
|
event.Skip();
|
||||||
|
}
|
||||||
|
|
||||||
static wxBitmap* ms_doubleBuffer;
|
static wxBitmap* ms_doubleBuffer;
|
||||||
|
|
||||||
|
DECLARE_EVENT_TABLE()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
BEGIN_EVENT_TABLE(wxSimpleCheckBox, wxControl)
|
||||||
|
EVT_PAINT(wxSimpleCheckBox::OnPaint)
|
||||||
|
EVT_LEFT_DOWN(wxSimpleCheckBox::OnLeftClick)
|
||||||
|
EVT_LEFT_DCLICK(wxSimpleCheckBox::OnLeftClick)
|
||||||
|
EVT_KEY_DOWN(wxSimpleCheckBox::OnKeyDown)
|
||||||
|
EVT_SIZE(wxSimpleCheckBox::OnResize)
|
||||||
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
wxSimpleCheckBox::~wxSimpleCheckBox()
|
wxSimpleCheckBox::~wxSimpleCheckBox()
|
||||||
{
|
{
|
||||||
delete ms_doubleBuffer;
|
delete ms_doubleBuffer;
|
||||||
ms_doubleBuffer = NULL;
|
ms_doubleBuffer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
wxBitmap* wxSimpleCheckBox::ms_doubleBuffer = (wxBitmap*) NULL;
|
wxBitmap* wxSimpleCheckBox::ms_doubleBuffer = (wxBitmap*) NULL;
|
||||||
|
|
||||||
// value = 2 means toggle (sorry, too lazy to do constants)
|
void wxSimpleCheckBox::OnPaint( wxPaintEvent& WXUNUSED(event) )
|
||||||
|
{
|
||||||
|
wxSize clientSize = GetClientSize();
|
||||||
|
wxAutoBufferedPaintDC dc(this);
|
||||||
|
|
||||||
|
dc.Clear();
|
||||||
|
wxRect rect(0,0,clientSize.x,clientSize.y);
|
||||||
|
rect.y += 1;
|
||||||
|
rect.width += 1;
|
||||||
|
|
||||||
|
wxColour bgcol = GetBackgroundColour();
|
||||||
|
dc.SetBrush( bgcol );
|
||||||
|
dc.SetPen( bgcol );
|
||||||
|
dc.DrawRectangle( rect );
|
||||||
|
|
||||||
|
wxColour txcol = GetForegroundColour();
|
||||||
|
|
||||||
|
int state = m_state;
|
||||||
|
if ( !(state & wxSCB_STATE_UNSPECIFIED) &&
|
||||||
|
m_font.GetWeight() == wxBOLD )
|
||||||
|
state |= wxSCB_STATE_BOLD;
|
||||||
|
|
||||||
|
DrawSimpleCheckBox(dc,rect,m_boxHeight,state,txcol);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxSimpleCheckBox::OnLeftClick( wxMouseEvent& event )
|
||||||
|
{
|
||||||
|
if ( (event.m_x > (wxPG_XBEFORETEXT-2)) &&
|
||||||
|
(event.m_x <= (wxPG_XBEFORETEXT-2+m_boxHeight)) )
|
||||||
|
{
|
||||||
|
SetValue(wxSCB_SETVALUE_CYCLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxSimpleCheckBox::OnKeyDown( wxKeyEvent& event )
|
||||||
|
{
|
||||||
|
if ( event.GetKeyCode() == WXK_SPACE )
|
||||||
|
{
|
||||||
|
SetValue(wxSCB_SETVALUE_CYCLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void wxSimpleCheckBox::SetValue( int value )
|
void wxSimpleCheckBox::SetValue( int value )
|
||||||
{
|
{
|
||||||
if ( value > 1 )
|
if ( value == wxSCB_SETVALUE_CYCLE )
|
||||||
{
|
{
|
||||||
m_state++;
|
if ( m_state & wxSCB_STATE_CHECKED )
|
||||||
if ( m_state > 1 ) m_state = 0;
|
m_state &= ~wxSCB_STATE_CHECKED;
|
||||||
|
else
|
||||||
|
m_state |= wxSCB_STATE_CHECKED;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1303,92 +1378,6 @@ void wxSimpleCheckBox::SetValue( int value )
|
|||||||
propGrid->HandleCustomEditorEvent(evt);
|
propGrid->HandleCustomEditorEvent(evt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool wxSimpleCheckBox::ProcessEvent(wxEvent& event)
|
|
||||||
{
|
|
||||||
wxPropertyGrid* propGrid = (wxPropertyGrid*) GetParent()->GetParent();
|
|
||||||
wxASSERT( propGrid->IsKindOf(CLASSINFO(wxPropertyGrid)) );
|
|
||||||
|
|
||||||
if ( ( (event.GetEventType() == wxEVT_LEFT_DOWN || event.GetEventType() == wxEVT_LEFT_DCLICK)
|
|
||||||
&& ((wxMouseEvent&)event).m_x > (wxPG_XBEFORETEXT-2)
|
|
||||||
&& ((wxMouseEvent&)event).m_x <= (wxPG_XBEFORETEXT-2+m_boxHeight) )
|
|
||||||
)
|
|
||||||
{
|
|
||||||
SetValue(2);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if ( event.GetEventType() == wxEVT_PAINT )
|
|
||||||
{
|
|
||||||
wxSize clientSize = GetClientSize();
|
|
||||||
wxPaintDC dc(this);
|
|
||||||
|
|
||||||
/*
|
|
||||||
// Buffered paint DC doesn't seem to do much good
|
|
||||||
if ( !ms_doubleBuffer ||
|
|
||||||
clientSize.x > ms_doubleBuffer->GetWidth() ||
|
|
||||||
clientSize.y > ms_doubleBuffer->GetHeight() )
|
|
||||||
{
|
|
||||||
delete ms_doubleBuffer;
|
|
||||||
ms_doubleBuffer = new wxBitmap(clientSize.x+25,clientSize.y+25);
|
|
||||||
}
|
|
||||||
|
|
||||||
wxBufferedPaintDC dc(this,*ms_doubleBuffer);
|
|
||||||
*/
|
|
||||||
|
|
||||||
wxRect rect(0,0,clientSize.x,clientSize.y);
|
|
||||||
//rect.x -= 1;
|
|
||||||
rect.y += 1;
|
|
||||||
rect.width += 1;
|
|
||||||
|
|
||||||
m_boxHeight = propGrid->GetFontHeight();
|
|
||||||
|
|
||||||
wxColour bgcol = GetBackgroundColour();
|
|
||||||
dc.SetBrush( bgcol );
|
|
||||||
dc.SetPen( bgcol );
|
|
||||||
dc.DrawRectangle( rect );
|
|
||||||
|
|
||||||
wxColour txcol = GetForegroundColour();
|
|
||||||
|
|
||||||
int state = m_state;
|
|
||||||
if ( m_font.GetWeight() == wxBOLD )
|
|
||||||
state |= 2;
|
|
||||||
|
|
||||||
DrawSimpleCheckBox(dc,rect,m_boxHeight,state,txcol);
|
|
||||||
|
|
||||||
// If focused, indicate it somehow.
|
|
||||||
/*
|
|
||||||
if ( wxWindow::FindFocus() == this )
|
|
||||||
{
|
|
||||||
rect.x += 1;
|
|
||||||
rect.width -= 1;
|
|
||||||
|
|
||||||
wxPGDrawFocusRect(dc,rect);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if ( event.GetEventType() == wxEVT_SIZE ||
|
|
||||||
event.GetEventType() == wxEVT_SET_FOCUS ||
|
|
||||||
event.GetEventType() == wxEVT_KILL_FOCUS
|
|
||||||
)
|
|
||||||
{
|
|
||||||
Refresh();
|
|
||||||
}
|
|
||||||
else if ( event.GetEventType() == wxEVT_KEY_DOWN )
|
|
||||||
{
|
|
||||||
wxKeyEvent& keyEv = (wxKeyEvent&) event;
|
|
||||||
|
|
||||||
if ( keyEv.GetKeyCode() == WXK_SPACE )
|
|
||||||
{
|
|
||||||
SetValue(2);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return wxControl::ProcessEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
wxPGWindowList wxPGCheckBoxEditor::CreateControls( wxPropertyGrid* propGrid,
|
wxPGWindowList wxPGCheckBoxEditor::CreateControls( wxPropertyGrid* propGrid,
|
||||||
wxPGProperty* property,
|
wxPGProperty* property,
|
||||||
const wxPoint& pos,
|
const wxPoint& pos,
|
||||||
@@ -1399,27 +1388,31 @@ wxPGWindowList wxPGCheckBoxEditor::CreateControls( wxPropertyGrid* propGrid,
|
|||||||
wxSize sz = size;
|
wxSize sz = size;
|
||||||
sz.x = propGrid->GetFontHeight() + (wxPG_XBEFOREWIDGET*2) + 4;
|
sz.x = propGrid->GetFontHeight() + (wxPG_XBEFOREWIDGET*2) + 4;
|
||||||
|
|
||||||
wxSimpleCheckBox* cb = new wxSimpleCheckBox(propGrid->GetPanel(),wxPG_SUBID1,pt,sz);
|
wxSimpleCheckBox* cb = new wxSimpleCheckBox(propGrid->GetPanel(),
|
||||||
|
wxPG_SUBID1, pt, sz);
|
||||||
|
|
||||||
cb->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
|
cb->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
|
||||||
|
|
||||||
if ( property->GetChoiceSelection() > 0 &&
|
UpdateControl(property, cb);
|
||||||
!property->IsValueUnspecified() )
|
|
||||||
cb->m_state = 1;
|
|
||||||
|
|
||||||
// If mouse cursor was on the item, toggle the value now.
|
if ( !property->IsValueUnspecified() )
|
||||||
if ( propGrid->GetInternalFlags() & wxPG_FL_ACTIVATION_BY_CLICK )
|
|
||||||
{
|
{
|
||||||
wxPoint pt = cb->ScreenToClient(::wxGetMousePosition());
|
// If mouse cursor was on the item, toggle the value now.
|
||||||
if ( pt.x <= (wxPG_XBEFORETEXT-2+cb->m_boxHeight) )
|
if ( propGrid->GetInternalFlags() & wxPG_FL_ACTIVATION_BY_CLICK )
|
||||||
{
|
{
|
||||||
cb->m_state++;
|
wxPoint pt = cb->ScreenToClient(::wxGetMousePosition());
|
||||||
|
if ( pt.x <= (wxPG_XBEFORETEXT-2+cb->m_boxHeight) )
|
||||||
|
{
|
||||||
|
if ( cb->m_state & wxSCB_STATE_CHECKED )
|
||||||
|
cb->m_state &= ~wxSCB_STATE_CHECKED;
|
||||||
|
else
|
||||||
|
cb->m_state |= wxSCB_STATE_CHECKED;
|
||||||
|
|
||||||
if ( cb->m_state > 1 )
|
// Makes sure wxPG_EVT_CHANGING etc. is sent for this initial
|
||||||
cb->m_state = 0;
|
// click
|
||||||
|
propGrid->ChangePropertyValue(property,
|
||||||
// Makes sure wxPG_EVT_CHANGING etc. is sent for this initial click
|
wxPGVariant_Bool(cb->m_state));
|
||||||
propGrid->ChangePropertyValue(property, wxPGVariant_Bool(cb->m_state));
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1428,53 +1421,43 @@ wxPGWindowList wxPGCheckBoxEditor::CreateControls( wxPropertyGrid* propGrid,
|
|||||||
return cb;
|
return cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
void wxPGCheckBoxEditor::DrawValue( wxDC& dc, const wxRect& rect,
|
||||||
class wxPGCheckBoxRenderer : public wxPGDefaultRenderer
|
wxPGProperty* property,
|
||||||
|
const wxString& WXUNUSED(text) ) const
|
||||||
{
|
{
|
||||||
public:
|
int state = wxSCB_STATE_UNCHECKED;
|
||||||
|
wxColour rectCol = dc.GetTextForeground();
|
||||||
|
|
||||||
virtual void Render( wxDC& dc, const wxRect& rect,
|
|
||||||
const wxPropertyGrid* WXUNUSED(propertyGrid), wxPGProperty* property,
|
|
||||||
int WXUNUSED(column), int WXUNUSED(item), int WXUNUSED(flags) ) const
|
|
||||||
{
|
|
||||||
int state = 0;
|
|
||||||
if ( !(property->GetFlags() & wxPG_PROP_UNSPECIFIED) )
|
|
||||||
{
|
|
||||||
state = ((wxPGProperty*)property)->GetChoiceInfo((wxPGChoiceInfo*)NULL);
|
|
||||||
if ( dc.GetFont().GetWeight() == wxBOLD ) state |= 2;
|
|
||||||
}
|
|
||||||
DrawSimpleCheckBox(dc,rect,dc.GetCharHeight(),state,dc.GetTextForeground());
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
};
|
|
||||||
|
|
||||||
wxPGCheckBoxRenderer g_wxPGCheckBoxRenderer;
|
|
||||||
|
|
||||||
wxPGCellRenderer* wxPGCheckBoxEditor::GetCellRenderer() const
|
|
||||||
{
|
|
||||||
return &g_wxPGCheckBoxRenderer;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
void wxPGCheckBoxEditor::DrawValue( wxDC& dc, const wxRect& rect, wxPGProperty* property, const wxString& WXUNUSED(text) ) const
|
|
||||||
{
|
|
||||||
int state = 0;
|
|
||||||
if ( !property->IsValueUnspecified() )
|
if ( !property->IsValueUnspecified() )
|
||||||
{
|
{
|
||||||
state = property->GetChoiceSelection();
|
state = property->GetChoiceSelection();
|
||||||
if ( dc.GetFont().GetWeight() == wxBOLD ) state |= 2;
|
if ( dc.GetFont().GetWeight() == wxBOLD )
|
||||||
|
state |= wxSCB_STATE_BOLD;
|
||||||
}
|
}
|
||||||
DrawSimpleCheckBox(dc,rect,dc.GetCharHeight(),state,dc.GetTextForeground());
|
else
|
||||||
|
{
|
||||||
|
state |= wxSCB_STATE_UNSPECIFIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawSimpleCheckBox(dc, rect, dc.GetCharHeight(), state, rectCol);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxPGCheckBoxEditor::UpdateControl( wxPGProperty* property, wxWindow* ctrl ) const
|
void wxPGCheckBoxEditor::UpdateControl( wxPGProperty* property,
|
||||||
|
wxWindow* ctrl ) const
|
||||||
{
|
{
|
||||||
wxASSERT( ctrl );
|
wxSimpleCheckBox* cb = (wxSimpleCheckBox*) ctrl;
|
||||||
((wxSimpleCheckBox*)ctrl)->m_state = property->GetChoiceSelection();
|
wxASSERT( cb );
|
||||||
ctrl->Refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if ( !property->IsValueUnspecified() )
|
||||||
|
cb->m_state = property->GetChoiceSelection();
|
||||||
|
else
|
||||||
|
cb->m_state = wxSCB_STATE_UNSPECIFIED;
|
||||||
|
|
||||||
|
wxPropertyGrid* propGrid = property->GetGrid();
|
||||||
|
cb->m_boxHeight = propGrid->GetFontHeight();
|
||||||
|
|
||||||
|
cb->Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
bool wxPGCheckBoxEditor::OnEvent( wxPropertyGrid* WXUNUSED(propGrid), wxPGProperty* WXUNUSED(property),
|
bool wxPGCheckBoxEditor::OnEvent( wxPropertyGrid* WXUNUSED(propGrid), wxPGProperty* WXUNUSED(property),
|
||||||
wxWindow* WXUNUSED(ctrl), wxEvent& event ) const
|
wxWindow* WXUNUSED(ctrl), wxEvent& event ) const
|
||||||
|
Reference in New Issue
Block a user