bool editor/renderer added

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@6112 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2000-02-17 14:08:27 +00:00
parent 45816ddded
commit 508011ce6c
3 changed files with 265 additions and 35 deletions

View File

@@ -28,7 +28,6 @@
#include "wx/string.h" #include "wx/string.h"
#include "wx/scrolbar.h" #include "wx/scrolbar.h"
#include "wx/event.h" #include "wx/event.h"
#include "wx/textctrl.h"
#include "wx/combobox.h" #include "wx/combobox.h"
#include "wx/dynarray.h" #include "wx/dynarray.h"
#include "wx/timer.h" #include "wx/timer.h"
@@ -63,6 +62,9 @@ class WXDLLEXPORT wxGridRowLabelWindow;
class WXDLLEXPORT wxGridTableBase; class WXDLLEXPORT wxGridTableBase;
class WXDLLEXPORT wxGridWindow; class WXDLLEXPORT wxGridWindow;
class WXDLLEXPORT wxCheckBox;
class WXDLLEXPORT wxTextCtrl;
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxGridCellRenderer: this class is responsible for actually drawing the cell // wxGridCellRenderer: this class is responsible for actually drawing the cell
// in the grid. You may pass it to the wxGridCellAttr (below) to change the // in the grid. You may pass it to the wxGridCellAttr (below) to change the
@@ -102,6 +104,19 @@ public:
bool isSelected); bool isSelected);
}; };
// renderer for boolean fields
class WXDLLEXPORT wxGridCellBoolRenderer : public wxGridCellRenderer
{
public:
// draw a check mark or nothing
virtual void Draw(wxGrid& grid,
wxGridCellAttr& attr,
wxDC& dc,
const wxRect& rect,
int row, int col,
bool isSelected);
};
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxGridCellEditor: This class is responsible for providing and manipulating // wxGridCellEditor: This class is responsible for providing and manipulating
@@ -168,7 +183,7 @@ protected:
wxFont m_fontOld; wxFont m_fontOld;
}; };
// the editor for string/text data
class WXDLLEXPORT wxGridCellTextEditor : public wxGridCellEditor class WXDLLEXPORT wxGridCellTextEditor : public wxGridCellEditor
{ {
public: public:
@@ -192,6 +207,32 @@ private:
wxString m_startValue; wxString m_startValue;
}; };
// the editor for boolean data
class WXDLLEXPORT wxGridCellBoolEditor : public wxGridCellEditor
{
public:
virtual void Create(wxWindow* parent,
wxWindowID id,
wxEvtHandler* evtHandler);
virtual void SetSize(const wxRect& rect);
virtual void Show(bool show, wxGridCellAttr *attr = (wxGridCellAttr *)NULL);
virtual void BeginEdit(int row, int col, wxGrid* grid);
virtual bool EndEdit(int row, int col, bool saveValue, wxGrid* grid);
virtual void Reset();
virtual void StartingKey(wxKeyEvent& event);
protected:
wxCheckBox *CBox() const { return (wxCheckBox *)m_control; }
private:
bool m_startValue;
wxRect m_rectCell; // the total size of the cell
};
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxGridCellAttr: this class can be used to alter the cells appearance in // wxGridCellAttr: this class can be used to alter the cells appearance in
// the grid by changing their colour/font/... from default. An object of this // the grid by changing their colour/font/... from default. An object of this
@@ -541,17 +582,17 @@ public:
return *this; return *this;
} }
bool operator==( const wxGridCellCoords& other ) bool operator==( const wxGridCellCoords& other ) const
{ {
return (m_row == other.m_row && m_col == other.m_col); return (m_row == other.m_row && m_col == other.m_col);
} }
bool operator!=( const wxGridCellCoords& other ) bool operator!=( const wxGridCellCoords& other ) const
{ {
return (m_row != other.m_row || m_col != other.m_col); return (m_row != other.m_row || m_col != other.m_col);
} }
bool operator!() bool operator!() const
{ {
return (m_row == -1 && m_col == -1 ); return (m_row == -1 && m_col == -1 );
} }
@@ -1071,6 +1112,9 @@ public:
wxGRID_CHOICE, wxGRID_CHOICE,
wxGRID_COMBOBOX }; wxGRID_COMBOBOX };
// for wxGridCellBoolEditor
wxWindow *GetGridWindow() const;
protected: protected:
bool m_created; bool m_created;
bool m_displayed; bool m_displayed;

View File

@@ -208,6 +208,10 @@ GridFrame::GridFrame()
grid->SetCellAlignment(4, 4, wxCENTRE, wxCENTRE); grid->SetCellAlignment(4, 4, wxCENTRE, wxCENTRE);
grid->SetCellRenderer(4, 4, new MyGridCellRenderer); grid->SetCellRenderer(4, 4, new MyGridCellRenderer);
grid->SetCellValue(3, 0, "1");
grid->SetCellRenderer(3, 0, new wxGridCellBoolRenderer);
grid->SetCellEditor(3, 0, new wxGridCellBoolEditor);
wxGridCellAttr *attr; wxGridCellAttr *attr;
attr = new wxGridCellAttr; attr = new wxGridCellAttr;
attr->SetTextColour(*wxBLUE); attr->SetTextColour(*wxBLUE);

View File

@@ -39,6 +39,8 @@
#include "wx/dcclient.h" #include "wx/dcclient.h"
#include "wx/settings.h" #include "wx/settings.h"
#include "wx/log.h" #include "wx/log.h"
#include "wx/textctrl.h"
#include "wx/checkbox.h"
#endif #endif
// this include needs to be outside precomp for BCC // this include needs to be outside precomp for BCC
@@ -289,10 +291,18 @@ wxGridCellEditor::~wxGridCellEditor()
Destroy(); Destroy();
} }
void wxGridCellEditor::Create(wxWindow* WXUNUSED(parent),
wxWindowID WXUNUSED(id),
wxEvtHandler* evtHandler)
{
if (evtHandler)
m_control->PushEventHandler(evtHandler);
}
void wxGridCellEditor::Destroy() void wxGridCellEditor::Destroy()
{ {
if (m_control) { if (m_control)
{
m_control->Destroy(); m_control->Destroy();
m_control = NULL; m_control = NULL;
} }
@@ -388,15 +398,14 @@ void wxGridCellTextEditor::Create(wxWindow* parent,
wxWindowID id, wxWindowID id,
wxEvtHandler* evtHandler) wxEvtHandler* evtHandler)
{ {
m_control = new wxTextCtrl(parent, -1, "", m_control = new wxTextCtrl(parent, id, wxEmptyString,
wxDefaultPosition, wxDefaultSize wxDefaultPosition, wxDefaultSize
#if defined(__WXMSW__) #if defined(__WXMSW__)
, wxTE_MULTILINE | wxTE_NO_VSCROLL // necessary ??? , wxTE_MULTILINE | wxTE_NO_VSCROLL // necessary ???
#endif #endif
); );
if (evtHandler) wxGridCellEditor::Create(parent, id, evtHandler);
m_control->PushEventHandler(evtHandler);
} }
@@ -412,7 +421,6 @@ void wxGridCellTextEditor::BeginEdit(int row, int col, wxGrid* grid)
} }
bool wxGridCellTextEditor::EndEdit(int row, int col, bool saveValue, bool wxGridCellTextEditor::EndEdit(int row, int col, bool saveValue,
wxGrid* grid) wxGrid* grid)
{ {
@@ -483,6 +491,107 @@ void wxGridCellTextEditor::HandleReturn(wxKeyEvent& event)
#endif #endif
} }
// ----------------------------------------------------------------------------
// wxGridCellBoolEditor
// ----------------------------------------------------------------------------
void wxGridCellBoolEditor::Create(wxWindow* parent,
wxWindowID id,
wxEvtHandler* evtHandler)
{
m_control = new wxCheckBox(parent, id, wxEmptyString,
wxDefaultPosition, wxDefaultSize,
wxNO_BORDER);
wxGridCellEditor::Create(parent, id, evtHandler);
}
void wxGridCellBoolEditor::SetSize(const wxRect& r)
{
m_rectCell = r;
// position it in the centre of the rectangle (TODO: support alignment?)
wxCoord w, h;
m_control->GetSize(&w, &h);
// the checkbox without label still has some space to the right in wxGTK,
// so shift it to the right
#ifdef __WXGTK__
w += 8;
#endif // GTK
m_control->Move(r.x + r.width/2 - w/2, r.y + r.height/2 - h/2);
}
void wxGridCellBoolEditor::Show(bool show, wxGridCellAttr *attr)
{
wxGridCellEditor::Show(show, attr);
if ( !show )
return;
// get the bg colour to use
wxColour colBg = attr ? attr->GetBackgroundColour() : *wxLIGHT_GREY;
// erase the background because we don't fill the cell
if ( m_rectCell.width > 0 )
{
wxClientDC dc(m_control->GetParent());
dc.SetPen(*wxTRANSPARENT_PEN);
dc.SetBrush(wxBrush(colBg, wxSOLID));
dc.DrawRectangle(m_rectCell);
m_rectCell.width = 0;
}
CBox()->SetBackgroundColour(colBg);
}
void wxGridCellBoolEditor::BeginEdit(int row, int col, wxGrid* grid)
{
wxASSERT_MSG(m_control,
wxT("The wxGridCellEditor must be Created first!"));
m_startValue = !!grid->GetTable()->GetValue(row, col); // FIXME-DATA
CBox()->SetValue(m_startValue);
CBox()->SetFocus();
}
bool wxGridCellBoolEditor::EndEdit(int row, int col,
bool saveValue,
wxGrid* grid)
{
wxASSERT_MSG(m_control,
wxT("The wxGridCellEditor must be Created first!"));
bool changed = FALSE;
bool value = CBox()->GetValue();
if ( value != m_startValue )
changed = TRUE;
if ( changed )
{
// FIXME-DATA
grid->GetTable()->SetValue(row, col, value ? _T("1") : wxEmptyString);
}
return changed;
}
void wxGridCellBoolEditor::Reset()
{
wxASSERT_MSG(m_control,
wxT("The wxGridCellEditor must be Created first!"));
CBox()->SetValue(m_startValue);
}
void wxGridCellBoolEditor::StartingKey(wxKeyEvent& event)
{
event.Skip();
}
// ----------------------------------------------------------------------------
// wxGridCellEditorEvtHandler
// ----------------------------------------------------------------------------
void wxGridCellEditorEvtHandler::OnKeyDown(wxKeyEvent& event) void wxGridCellEditorEvtHandler::OnKeyDown(wxKeyEvent& event)
{ {
@@ -522,6 +631,10 @@ void wxGridCellEditorEvtHandler::OnChar(wxKeyEvent& event)
} }
} }
// ============================================================================
// renderer classes
// ============================================================================
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxGridCellRenderer // wxGridCellRenderer
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -548,6 +661,10 @@ void wxGridCellRenderer::Draw(wxGrid& grid,
dc.DrawRectangle(rect); dc.DrawRectangle(rect);
} }
// ----------------------------------------------------------------------------
// wxGridCellStringRenderer
// ----------------------------------------------------------------------------
void wxGridCellStringRenderer::Draw(wxGrid& grid, void wxGridCellStringRenderer::Draw(wxGrid& grid,
wxGridCellAttr& attr, wxGridCellAttr& attr,
wxDC& dc, wxDC& dc,
@@ -587,6 +704,40 @@ void wxGridCellStringRenderer::Draw(wxGrid& grid,
rect, hAlign, vAlign); rect, hAlign, vAlign);
} }
// ----------------------------------------------------------------------------
// wxGridCellBoolRenderer
// ----------------------------------------------------------------------------
void wxGridCellBoolRenderer::Draw(wxGrid& grid,
wxGridCellAttr& attr,
wxDC& dc,
const wxRect& rect,
int row, int col,
bool isSelected)
{
wxGridCellRenderer::Draw(grid, attr, dc, rect, row, col, isSelected);
// position it in the centre (ignoring alignment - TODO)
static const wxCoord checkSize = 16;
wxRect rectMark;
rectMark.x = rect.x + rect.width/2 - checkSize/2;
rectMark.y = rect.y + rect.height/2 - checkSize/2;
rectMark.width = rectMark.height = checkSize;
dc.SetBrush(*wxTRANSPARENT_BRUSH);
dc.SetPen(wxPen(attr.GetTextColour(), 1, wxSOLID));
dc.DrawRectangle(rectMark);
rectMark.Inflate(-4);
if ( !!grid.GetTable()->GetValue(row, col) ) // FIXME-DATA
{
dc.SetTextForeground(attr.GetTextColour());
dc.DrawCheckMark(rectMark);
}
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxGridCellAttr // wxGridCellAttr
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -594,10 +745,15 @@ void wxGridCellStringRenderer::Draw(wxGrid& grid,
const wxColour& wxGridCellAttr::GetTextColour() const const wxColour& wxGridCellAttr::GetTextColour() const
{ {
if (HasTextColour()) if (HasTextColour())
{
return m_colText; return m_colText;
}
else if (m_defGridAttr != this) else if (m_defGridAttr != this)
{
return m_defGridAttr->GetTextColour(); return m_defGridAttr->GetTextColour();
else { }
else
{
wxFAIL_MSG(wxT("Missing default cell attribute")); wxFAIL_MSG(wxT("Missing default cell attribute"));
return wxNullColour; return wxNullColour;
} }
@@ -610,7 +766,8 @@ const wxColour& wxGridCellAttr::GetBackgroundColour() const
return m_colBack; return m_colBack;
else if (m_defGridAttr != this) else if (m_defGridAttr != this)
return m_defGridAttr->GetBackgroundColour(); return m_defGridAttr->GetBackgroundColour();
else { else
{
wxFAIL_MSG(wxT("Missing default cell attribute")); wxFAIL_MSG(wxT("Missing default cell attribute"));
return wxNullColour; return wxNullColour;
} }
@@ -623,7 +780,8 @@ const wxFont& wxGridCellAttr::GetFont() const
return m_font; return m_font;
else if (m_defGridAttr != this) else if (m_defGridAttr != this)
return m_defGridAttr->GetFont(); return m_defGridAttr->GetFont();
else { else
{
wxFAIL_MSG(wxT("Missing default cell attribute")); wxFAIL_MSG(wxT("Missing default cell attribute"));
return wxNullFont; return wxNullFont;
} }
@@ -632,13 +790,15 @@ const wxFont& wxGridCellAttr::GetFont() const
void wxGridCellAttr::GetAlignment(int *hAlign, int *vAlign) const void wxGridCellAttr::GetAlignment(int *hAlign, int *vAlign) const
{ {
if (HasAlignment()) { if (HasAlignment())
{
if ( hAlign ) *hAlign = m_hAlign; if ( hAlign ) *hAlign = m_hAlign;
if ( vAlign ) *vAlign = m_vAlign; if ( vAlign ) *vAlign = m_vAlign;
} }
else if (m_defGridAttr != this) else if (m_defGridAttr != this)
m_defGridAttr->GetAlignment(hAlign, vAlign); m_defGridAttr->GetAlignment(hAlign, vAlign);
else { else
{
wxFAIL_MSG(wxT("Missing default cell attribute")); wxFAIL_MSG(wxT("Missing default cell attribute"));
} }
} }
@@ -650,7 +810,8 @@ wxGridCellRenderer* wxGridCellAttr::GetRenderer() const
return m_renderer; return m_renderer;
else if (m_defGridAttr != this) else if (m_defGridAttr != this)
return m_defGridAttr->GetRenderer(); return m_defGridAttr->GetRenderer();
else { else
{
wxFAIL_MSG(wxT("Missing default cell attribute")); wxFAIL_MSG(wxT("Missing default cell attribute"));
return NULL; return NULL;
} }
@@ -662,7 +823,8 @@ wxGridCellEditor* wxGridCellAttr::GetEditor() const
return m_editor; return m_editor;
else if (m_defGridAttr != this) else if (m_defGridAttr != this)
return m_defGridAttr->GetEditor(); return m_defGridAttr->GetEditor();
else { else
{
wxFAIL_MSG(wxT("Missing default cell attribute")); wxFAIL_MSG(wxT("Missing default cell attribute"));
return NULL; return NULL;
} }
@@ -2861,8 +3023,10 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event )
// Don't start doing anything until the mouse has been drug at // Don't start doing anything until the mouse has been drug at
// least 3 pixels in any direction... // least 3 pixels in any direction...
if (! m_isDragging) { if (! m_isDragging)
if (m_startDragPos == wxDefaultPosition) { {
if (m_startDragPos == wxDefaultPosition)
{
m_startDragPos = pos; m_startDragPos = pos;
return; return;
} }
@@ -2879,7 +3043,8 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event )
HideCellEditControl(); HideCellEditControl();
// Have we captured the mouse yet? // Have we captured the mouse yet?
if (! m_winCapture) { if (! m_winCapture)
{
m_winCapture = m_gridWin; m_winCapture = m_gridWin;
m_winCapture->CaptureMouse(); m_winCapture->CaptureMouse();
} }
@@ -2895,7 +3060,8 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event )
SelectBlock( m_currentCellCoords, coords ); SelectBlock( m_currentCellCoords, coords );
} }
if (! IsVisible(coords)) { if (! IsVisible(coords))
{
MakeCellVisible(coords); MakeCellVisible(coords);
// TODO: need to introduce a delay or something here. The // TODO: need to introduce a delay or something here. The
// scrolling is way to fast, at least on MSW. // scrolling is way to fast, at least on MSW.
@@ -3024,7 +3190,8 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event )
{ {
if ( IsSelection() ) if ( IsSelection() )
{ {
if (m_winCapture) { if (m_winCapture)
{
m_winCapture->ReleaseMouse(); m_winCapture->ReleaseMouse();
m_winCapture = NULL; m_winCapture = NULL;
} }
@@ -3758,10 +3925,8 @@ void wxGrid::OnKeyDown( wxKeyEvent& event )
void wxGrid::OnEraseBackground(wxEraseEvent&) void wxGrid::OnEraseBackground(wxEraseEvent&)
{ } {
}
void wxGrid::SetCurrentCell( const wxGridCellCoords& coords ) void wxGrid::SetCurrentCell( const wxGridCellCoords& coords )
{ {
@@ -3882,6 +4047,10 @@ void wxGrid::DrawCell( wxDC& dc, const wxGridCellCoords& coords )
DrawCellBorder( dc, coords ); DrawCellBorder( dc, coords );
#endif #endif
// don't draw the cell over the active edit control!
if ( (coords == m_currentCellCoords) && IsCellEditControlEnabled() )
return;
// but all the rest is drawn by the cell renderer and hence may be // but all the rest is drawn by the cell renderer and hence may be
// customized // customized
wxRect rect; wxRect rect;
@@ -3986,7 +4155,8 @@ void wxGrid::DrawAllGridLines( wxDC& dc, const wxRegion & reg )
int top, bottom, left, right; int top, bottom, left, right;
if (reg.IsEmpty()){ if (reg.IsEmpty())
{
int cw, ch; int cw, ch;
m_gridWin->GetClientSize(&cw, &ch); m_gridWin->GetClientSize(&cw, &ch);
@@ -3995,7 +4165,8 @@ void wxGrid::DrawAllGridLines( wxDC& dc, const wxRegion & reg )
CalcUnscrolledPosition( 0, 0, &left, &top ); CalcUnscrolledPosition( 0, 0, &left, &top );
CalcUnscrolledPosition( cw, ch, &right, &bottom ); CalcUnscrolledPosition( cw, ch, &right, &bottom );
} }
else{ else
{
wxCoord x, y, w, h; wxCoord x, y, w, h;
reg.GetBox(x, y, w, h); reg.GetBox(x, y, w, h);
CalcUnscrolledPosition( x, y, &left, &top ); CalcUnscrolledPosition( x, y, &left, &top );
@@ -4334,6 +4505,11 @@ bool wxGrid::IsCellEditControlEnabled() const
return m_cellEditCtrlEnabled ? !IsCurrentCellReadOnly() : FALSE; return m_cellEditCtrlEnabled ? !IsCurrentCellReadOnly() : FALSE;
} }
wxWindow *wxGrid::GetGridWindow() const
{
return m_gridWin;
}
void wxGrid::ShowCellEditControl() void wxGrid::ShowCellEditControl()
{ {
if ( IsCellEditControlEnabled() ) if ( IsCellEditControlEnabled() )
@@ -4353,9 +4529,12 @@ void wxGrid::ShowCellEditControl()
int left, top, right, bottom; int left, top, right, bottom;
CalcScrolledPosition( rect.GetLeft(), rect.GetTop(), &left, &top ); CalcScrolledPosition( rect.GetLeft(), rect.GetTop(), &left, &top );
CalcScrolledPosition( rect.GetRight(), rect.GetBottom(), &right, &bottom ); CalcScrolledPosition( rect.GetRight(), rect.GetBottom(), &right, &bottom );
left--; top--; right--; bottom--; // cell is shifted by one pixel
int cw, ch; // cell is shifted by one pixel
m_gridWin->GetClientSize( &cw, &ch ); left--;
top--;
right--;
bottom--;
// Make the edit control large enough to allow for internal // Make the edit control large enough to allow for internal
// margins // margins
@@ -4400,7 +4579,7 @@ void wxGrid::ShowCellEditControl()
rect.SetBottom( rect.GetBottom() + 2*extra ); rect.SetBottom( rect.GetBottom() + 2*extra );
#endif #endif
wxGridCellAttr* attr = GetCellAttr(row, col); wxGridCellAttr* attr = GetCellAttr(row, col);
wxGridCellEditor* editor = attr->GetEditor(); wxGridCellEditor* editor = attr->GetEditor();
if ( !editor->IsCreated() ) if ( !editor->IsCreated() )
{ {
@@ -5515,9 +5694,12 @@ wxGridCellAttr *wxGrid::GetCellAttr(int row, int col) const
attr = m_table ? m_table->GetAttr(row, col) : (wxGridCellAttr *)NULL; attr = m_table ? m_table->GetAttr(row, col) : (wxGridCellAttr *)NULL;
CacheAttr(row, col, attr); CacheAttr(row, col, attr);
} }
if (attr) { if (attr)
{
attr->SetDefAttr(m_defaultCellAttr); attr->SetDefAttr(m_defaultCellAttr);
} else { }
else
{
attr = m_defaultCellAttr; attr = m_defaultCellAttr;
attr->IncRef(); attr->IncRef();
} }