From 816be743e86d10387376fa87ddb2fc684eb1efd3 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 22 Feb 2000 14:29:41 +0000 Subject: [PATCH] added renderers/editors for long/float, not fully tested yet, but seems to work - see the demo in the (updated) sample git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@6210 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/generic/grid.h | 127 +++++++++++++- samples/newgrid/griddemo.cpp | 310 ++++++++++++++++++++++++++------ samples/newgrid/griddemo.h | 44 +++-- src/generic/grid.cpp | 332 ++++++++++++++++++++++++++++++++--- 4 files changed, 712 insertions(+), 101 deletions(-) diff --git a/include/wx/generic/grid.h b/include/wx/generic/grid.h index c27cebb530..3c10ae8507 100644 --- a/include/wx/generic/grid.h +++ b/include/wx/generic/grid.h @@ -32,6 +32,10 @@ #include "wx/dynarray.h" #include "wx/timer.h" +// ---------------------------------------------------------------------------- +// constants +// ---------------------------------------------------------------------------- + // Default parameters for wxGrid // #define WXGRID_DEFAULT_NUMBER_ROWS 10 @@ -49,6 +53,15 @@ #define WXGRID_MIN_COL_WIDTH 15 #define WXGRID_DEFAULT_SCROLLBAR_WIDTH 16 +// type names for grid table values +#define wxGRID_VALUE_STRING _T("string") +#define wxGRID_VALUE_BOOL _T("bool") +#define wxGRID_VALUE_NUMBER _T("long") +#define wxGRID_VALUE_FLOAT _T("double") + +#define wxGRID_VALUE_TEXT wxGRID_VALUE_STRING +#define wxGRID_VALUE_LONG wxGRID_VALUE_NUMBER + // ---------------------------------------------------------------------------- // forward declarations // ---------------------------------------------------------------------------- @@ -65,6 +78,7 @@ class WXDLLEXPORT wxGridTypeRegistry; class WXDLLEXPORT wxCheckBox; class WXDLLEXPORT wxTextCtrl; +class WXDLLEXPORT wxSpinCtrl; // ---------------------------------------------------------------------------- // wxGridCellRenderer: this class is responsible for actually drawing the cell @@ -90,6 +104,9 @@ public: const wxRect& rect, int row, int col, bool isSelected) = 0; + + // virtual dtor for any base class + virtual ~wxGridCellRenderer(); }; // the default renderer for the cells containing string data @@ -103,13 +120,59 @@ public: const wxRect& rect, int row, int col, bool isSelected); + +protected: + // set the text colours before drawing + void SetTextColoursAndFont(wxGrid& grid, + wxGridCellAttr& attr, + wxDC& dc, + bool isSelected); +}; + +// the default renderer for the cells containing numeric (long) data +class WXDLLEXPORT wxGridCellNumberRenderer : public wxGridCellStringRenderer +{ +public: + // draw the string right aligned + virtual void Draw(wxGrid& grid, + wxGridCellAttr& attr, + wxDC& dc, + const wxRect& rect, + int row, int col, + bool isSelected); +}; + +class WXDLLEXPORT wxGridCellFloatRenderer : public wxGridCellStringRenderer +{ +public: + wxGridCellFloatRenderer(int width, int precision); + + // get/change formatting parameters + int GetWidth() const { return m_width; } + void SetWidth(int width) { m_width = width; } + int GetPrecision() const { return m_precision; } + void SetPrecision(int precision) { m_precision = precision; } + + // draw the string right aligned with given width/precision + virtual void Draw(wxGrid& grid, + wxGridCellAttr& attr, + wxDC& dc, + const wxRect& rect, + int row, int col, + bool isSelected); + +private: + // formatting parameters + int m_width, + m_precision; + + wxString m_format; }; // renderer for boolean fields class WXDLLEXPORT wxGridCellBoolRenderer : public wxGridCellRenderer { public: - // draw a check mark or nothing virtual void Draw(wxGrid& grid, wxGridCellAttr& attr, @@ -215,10 +278,72 @@ public: protected: wxTextCtrl *Text() const { return (wxTextCtrl *)m_control; } + // parts of our virtual functions reused by the derived classes + void DoBeginEdit(const wxString& startValue); + void DoReset(const wxString& startValue); + private: wxString m_startValue; }; +// the editor for numeric (long) data +class WXDLLEXPORT wxGridCellNumberEditor : public wxGridCellTextEditor +{ +public: + // allows to specify the range - if min == max == -1, no range checking is + // done + wxGridCellNumberEditor(int min = -1, int max = -1); + + virtual void Create(wxWindow* parent, + wxWindowID id, + wxEvtHandler* evtHandler); + + 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: + wxSpinCtrl *Spin() const { return (wxSpinCtrl *)m_control; } + + // if HasRange(), we use wxSpinCtrl - otherwise wxTextCtrl + bool HasRange() const { return m_min != m_max; } + + // string representation of m_valueOld + wxString GetString() const + { return wxString::Format(_T("%ld"), m_valueOld); } + +private: + int m_min, + m_max; + + long m_valueOld; +}; + +// the editor for floating point numbers (double) data +class WXDLLEXPORT wxGridCellFloatEditor : public wxGridCellTextEditor +{ +public: + virtual void Create(wxWindow* parent, + wxWindowID id, + wxEvtHandler* evtHandler); + + 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: + // string representation of m_valueOld + wxString GetString() const + { return wxString::Format(_T("%f"), m_valueOld); } + +private: + double m_valueOld; +}; + // the editor for boolean data class WXDLLEXPORT wxGridCellBoolEditor : public wxGridCellEditor { diff --git a/samples/newgrid/griddemo.cpp b/samples/newgrid/griddemo.cpp index 3a7f00e66c..b73608eed9 100644 --- a/samples/newgrid/griddemo.cpp +++ b/samples/newgrid/griddemo.cpp @@ -186,10 +186,8 @@ GridFrame::GridFrame() logger->SetTimestamp( NULL ); // this will create a grid and, by default, an associated grid - // table for string data - // - //grid->CreateGrid( 100, 100 ); - grid->SetTable(new SimpleTable(100, 100), TRUE); + // table for string gs_dataBugsGrid + grid->CreateGrid( 100, 100 ); grid->SetRowSize( 0, 60 ); grid->SetCellValue( 0, 0, "Ctrl+Home\nwill go to\nthis cell" ); @@ -695,74 +693,274 @@ BigGridFrame::BigGridFrame(long sizeGrid) // BugsGridFrame: a "realistic" table // ---------------------------------------------------------------------------- -BugsGridFrame::BugsGridFrame() - : wxFrame(NULL, -1, "Bugs table", - wxDefaultPosition, wxSize(500, 300)) +enum Columns +{ + Col_Id, + Col_Summary, + Col_Severity, + Col_Priority, + Col_Platform, + Col_Opened, + Col_Max +}; + +enum Severity +{ + Sev_Wish, + Sev_Minor, + Sev_Normal, + Sev_Major, + Sev_Critical, + Sev_Max +}; + +static const wxChar* severities[] = +{ + _T("wishlist"), + _T("minor"), + _T("normal"), + _T("major"), + _T("critical"), +}; + +static struct BugsGridData +{ + int id; + const wxChar *summary; + Severity severity; + int prio; + const wxChar *platform; + bool opened; +} gs_dataBugsGrid [] = +{ + { 18, _T("foo doesn't work"), Sev_Major, 1, _T("wxMSW"), TRUE }, + { 27, _T("bar crashes"), Sev_Critical, 1, _T("all"), FALSE }, + { 45, _T("printing is slow"), Sev_Minor, 3, _T("wxMSW"), TRUE }, + { 68, _T("Rectangle() fails"), Sev_Normal, 1, _T("wxMSW"), FALSE }, +}; + +static const wxChar *headers[Col_Max] = +{ + _T("Id"), + _T("Summary"), + _T("Severity"), + _T("Priority"), + _T("Platform"), + _T("Opened?"), +}; + +wxString BugsGridTable::GetTypeName(int WXUNUSED(row), int col) +{ + switch ( col ) + { + case Col_Id: + case Col_Priority: + return wxGRID_VALUE_NUMBER;; + + case Col_Severity: + // fall thorugh (TODO should be a list) + + case Col_Summary: + case Col_Platform: + return wxGRID_VALUE_STRING; + + case Col_Opened: + return wxGRID_VALUE_BOOL; + } + + wxFAIL_MSG(_T("unknown column")); + + return wxEmptyString; +} + +long BugsGridTable::GetNumberRows() +{ + return WXSIZEOF(gs_dataBugsGrid); +} + +long BugsGridTable::GetNumberCols() { - enum Severity + return Col_Max; +} + +bool BugsGridTable::IsEmptyCell( int row, int col ) +{ + return FALSE; +} + +wxString BugsGridTable::GetValue( int row, int col ) +{ + const BugsGridData& gd = gs_dataBugsGrid[row]; + + switch ( col ) { - Wish, - Minor, - Normal, - Major, - Critical - }; + case Col_Id: + case Col_Priority: + case Col_Opened: + wxFAIL_MSG(_T("unexpected column")); + break; + + case Col_Severity: + return severities[gd.severity]; + + case Col_Summary: + return gd.summary; + + case Col_Platform: + return gd.platform; + } + + return wxEmptyString; +} + +void BugsGridTable::SetValue( int row, int col, const wxString& value ) +{ + BugsGridData& gd = gs_dataBugsGrid[row]; - static const wxChar* severities[] = + switch ( col ) { - _T("wishlist"), - _T("minor"), - _T("normal"), - _T("major"), - _T("critical"), - }; + case Col_Id: + case Col_Priority: + case Col_Opened: + wxFAIL_MSG(_T("unexpected column")); + break; + + case Col_Severity: + { + size_t n; + for ( n = 0; n < WXSIZEOF(severities); n++ ) + { + if ( severities[n] == value ) + { + gd.severity = (Severity)n; + break; + } + } + + if ( n == WXSIZEOF(severities) ) + { + wxLogWarning(_T("Invalid severity value '%s'."), + value.c_str()); + gd.severity = Sev_Normal; + } + } + + case Col_Summary: + gd.summary = value; + break; - static const struct GridData + case Col_Platform: + gd.platform = value; + break; + } +} + +bool BugsGridTable::CanGetValueAs( int WXUNUSED(row), int col, const wxString& typeName ) +{ + if ( typeName == wxGRID_VALUE_STRING ) { - int id; - const wxChar *summary; - Severity severity; - int prio; - const wxChar *platform; - bool opened; - } data [] = + return TRUE; + } + else if ( typeName == wxGRID_VALUE_BOOL ) + { + return col == Col_Opened; + } + else if ( typeName == wxGRID_VALUE_NUMBER ) + { + return col == Col_Id || col == Col_Priority || col == Col_Severity; + } + else { - { 18, _T("foo doesn't work"), Major, 1, _T("wxMSW"), TRUE }, - { 27, _T("bar crashes"), Critical, 1, _T("all"), FALSE }, - { 45, _T("printing is slow"), Minor, 3, _T("wxMSW"), TRUE }, - { 68, _T("Rectangle() fails"), Normal, 1, _T("wxMSW"), FALSE }, - }; + return FALSE; + } +} + +bool BugsGridTable::CanSetValueAs( int row, int col, const wxString& typeName ) +{ + return CanGetValueAs(row, col, typeName); +} + +long BugsGridTable::GetValueAsLong( int row, int col ) +{ + const BugsGridData& gd = gs_dataBugsGrid[row]; - static const wxChar *headers[] = + switch ( col ) { - _T("Id"), - _T("Summary"), - _T("Severity"), - _T("Priority"), - _T("Platform"), - _T("Opened?"), - }; + case Col_Id: + return gd.id; - // TODO the correct data type must be used for each column + case Col_Priority: + return gd.prio; - wxGrid *grid = new wxGrid(this, -1, wxDefaultPosition); - wxGridTableBase *table = - new wxGridStringTable(WXSIZEOF(data), WXSIZEOF(headers)); - for ( size_t row = 0; row < WXSIZEOF(data); row++ ) + case Col_Severity: + return gd.severity; + + default: + wxFAIL_MSG(_T("unexpected column")); + return -1; + } +} + +bool BugsGridTable::GetValueAsBool( int row, int col ) +{ + if ( col == Col_Opened ) + { + return gs_dataBugsGrid[row].opened; + } + else { - const GridData& gd = data[row]; - table->SetValue(row, 0, wxString::Format("%d", gd.id)); - table->SetValue(row, 1, gd.summary); - table->SetValue(row, 2, severities[gd.severity]); - table->SetValue(row, 3, wxString::Format("%d", gd.prio)); - table->SetValue(row, 4, gd.platform); - table->SetValue(row, 5, gd.opened ? _T("True") : wxEmptyString); + wxFAIL_MSG(_T("unexpected column")); + + return FALSE; } +} - for ( size_t col = 0; col < WXSIZEOF(headers); col++ ) +void BugsGridTable::SetValueAsLong( int row, int col, long value ) +{ + BugsGridData& gd = gs_dataBugsGrid[row]; + + switch ( col ) { - table->SetColLabelValue(col, headers[col]); + case Col_Priority: + gd.prio = value; + break; + + default: + wxFAIL_MSG(_T("unexpected column")); } +} +void BugsGridTable::SetValueAsBool( int row, int col, bool value ) +{ + if ( col == Col_Opened ) + { + gs_dataBugsGrid[row].opened = value; + } + else + { + wxFAIL_MSG(_T("unexpected column")); + } +} + +wxString BugsGridTable::GetColLabelValue( int col ) +{ + return headers[col]; +} + +BugsGridTable::BugsGridTable() +{ +} + +BugsGridFrame::BugsGridFrame() + : wxFrame(NULL, -1, "Bugs table", + wxDefaultPosition, wxSize(500, 300)) +{ + wxGrid *grid = new wxGrid(this, -1, wxDefaultPosition); + wxGridTableBase *table = new BugsGridTable(); grid->SetTable(table, TRUE); + + for ( size_t row = 0; row < WXSIZEOF(gs_dataBugsGrid); row++ ) + { + grid->SetReadOnly(row, Col_Id); + } } diff --git a/samples/newgrid/griddemo.h b/samples/newgrid/griddemo.h index 4af53be960..3b27cf8f78 100644 --- a/samples/newgrid/griddemo.h +++ b/samples/newgrid/griddemo.h @@ -125,24 +125,6 @@ public: // memory // ---------------------------------------------------------------------------- -class SimpleTable : public wxGridStringTable { -public: - SimpleTable( int numRows, int numCols ) - : wxGridStringTable( numRows, numCols ) {} - - // override this to fake a row as all bools - wxString GetTypeName( int row, int col ) - { - if (row == 8) - return wxT("bool"); - else if (row == 9 && col == 1) - return wxT("unknown type"); // to test fallback - else - return wxGridStringTable::GetTypeName(row, col); - } - -}; - class BigGridTable : public wxGridTableBase { public: @@ -173,9 +155,33 @@ private: }; // ---------------------------------------------------------------------------- -// another, more realistic, grid example +// another, more realistic, grid example: shows typed columns and more // ---------------------------------------------------------------------------- +class BugsGridTable : public wxGridTableBase +{ +public: + BugsGridTable(); + + virtual long GetNumberRows(); + virtual long GetNumberCols(); + virtual bool IsEmptyCell( int row, int col ); + virtual wxString GetValue( int row, int col ); + virtual void SetValue( int row, int col, const wxString& value ); + + virtual wxString GetColLabelValue( int col ); + + virtual wxString GetTypeName( int row, int col ); + virtual bool CanGetValueAs( int row, int col, const wxString& typeName ); + virtual bool CanSetValueAs( int row, int col, const wxString& typeName ); + + virtual long GetValueAsLong( int row, int col ); + virtual bool GetValueAsBool( int row, int col ); + + virtual void SetValueAsLong( int row, int col, long value ); + virtual void SetValueAsBool( int row, int col, bool value ); +}; + class BugsGridFrame : public wxFrame { public: diff --git a/src/generic/grid.cpp b/src/generic/grid.cpp index e67268205c..d728ad8407 100644 --- a/src/generic/grid.cpp +++ b/src/generic/grid.cpp @@ -41,10 +41,11 @@ #include "wx/log.h" #include "wx/textctrl.h" #include "wx/checkbox.h" + #include "wx/valtext.h" #endif -// this include needs to be outside precomp for BCC #include "wx/textfile.h" +#include "wx/spinctrl.h" #include "wx/grid.h" @@ -500,12 +501,17 @@ void wxGridCellTextEditor::BeginEdit(int row, int col, wxGrid* grid) wxT("The wxGridCellEditor must be Created first!")); m_startValue = grid->GetTable()->GetValue(row, col); - Text()->SetValue(m_startValue); + + DoBeginEdit(m_startValue); +} + +void wxGridCellTextEditor::DoBeginEdit(const wxString& startValue) +{ + Text()->SetValue(startValue); Text()->SetInsertionPointEnd(); Text()->SetFocus(); } - bool wxGridCellTextEditor::EndEdit(int row, int col, bool saveValue, wxGrid* grid) { @@ -532,7 +538,12 @@ void wxGridCellTextEditor::Reset() wxASSERT_MSG(m_control, wxT("The wxGridCellEditor must be Created first!")); - Text()->SetValue(m_startValue); + DoReset(m_startValue); +} + +void wxGridCellTextEditor::DoReset(const wxString& startValue) +{ + Text()->SetValue(startValue); Text()->SetInsertionPointEnd(); } @@ -576,6 +587,187 @@ void wxGridCellTextEditor::HandleReturn(wxKeyEvent& event) #endif } +// ---------------------------------------------------------------------------- +// wxGridCellNumberEditor +// ---------------------------------------------------------------------------- + +wxGridCellNumberEditor::wxGridCellNumberEditor(int min, int max) +{ + m_min = min; + m_max = max; +} + +void wxGridCellNumberEditor::Create(wxWindow* parent, + wxWindowID id, + wxEvtHandler* evtHandler) +{ + if ( HasRange() ) + { + // create a spin ctrl + m_control = new wxSpinCtrl(parent, -1, wxEmptyString, + wxDefaultPosition, wxDefaultSize, + wxSP_ARROW_KEYS, + m_min, m_max); + + wxGridCellEditor::Create(parent, id, evtHandler); + } + else + { + // just a text control + wxGridCellTextEditor::Create(parent, id, evtHandler); + +#if wxUSE_VALIDATORS + Text()->SetValidator(new wxTextValidator(wxFILTER_NUMERIC)); +#endif // wxUSE_VALIDATORS + } +} + +void wxGridCellNumberEditor::BeginEdit(int row, int col, wxGrid* grid) +{ + // first get the value + wxGridTableBase *table = grid->GetTable(); + if ( table->CanGetValueAs(row, col, wxGRID_VALUE_NUMBER) ) + { + m_valueOld = table->GetValueAsLong(row, col); + } + else + { + wxFAIL_MSG( _T("this cell doesn't have numeric value") ); + + return; + } + + if ( HasRange() ) + { + Spin()->SetValue(m_valueOld); + } + else + { + DoBeginEdit(GetString()); + } +} + +bool wxGridCellNumberEditor::EndEdit(int row, int col, bool saveValue, + wxGrid* grid) +{ + bool changed; + long value; + + if ( HasRange() ) + { + value = Spin()->GetValue(); + changed = value != m_valueOld; + } + else + { + changed = Text()->GetValue().ToLong(&value) && (value != m_valueOld); + } + + if ( changed ) + { + grid->GetTable()->SetValueAsLong(row, col, value); + } + + return changed; +} + +void wxGridCellNumberEditor::Reset() +{ + if ( HasRange() ) + { + Spin()->SetValue(m_valueOld); + } + else + { + DoReset(GetString()); + } +} + +void wxGridCellNumberEditor::StartingKey(wxKeyEvent& event) +{ + if ( !HasRange() ) + { + long keycode = event.KeyCode(); + if ( isdigit(keycode) || keycode == '+' || keycode == '-' ) + { + wxGridCellTextEditor::StartingKey(event); + + // skip Skip() below + return; + } + } + + event.Skip(); +} +// ---------------------------------------------------------------------------- +// wxGridCellFloatEditor +// ---------------------------------------------------------------------------- + +void wxGridCellFloatEditor::Create(wxWindow* parent, + wxWindowID id, + wxEvtHandler* evtHandler) +{ + wxGridCellTextEditor::Create(parent, id, evtHandler); + +#if wxUSE_VALIDATORS + Text()->SetValidator(new wxTextValidator(wxFILTER_NUMERIC)); +#endif // wxUSE_VALIDATORS +} + +void wxGridCellFloatEditor::BeginEdit(int row, int col, wxGrid* grid) +{ + // first get the value + wxGridTableBase *table = grid->GetTable(); + if ( table->CanGetValueAs(row, col, wxGRID_VALUE_FLOAT) ) + { + m_valueOld = table->GetValueAsDouble(row, col); + } + else + { + wxFAIL_MSG( _T("this cell doesn't have float value") ); + + return; + } + + DoBeginEdit(GetString()); +} + +bool wxGridCellFloatEditor::EndEdit(int row, int col, bool saveValue, + wxGrid* grid) +{ + double value; + if ( Text()->GetValue().ToDouble(&value) && (value != m_valueOld) ) + { + grid->GetTable()->SetValueAsDouble(row, col, value); + + return TRUE; + } + else + { + return FALSE; + } +} + +void wxGridCellFloatEditor::Reset() +{ + DoReset(GetString()); +} + +void wxGridCellFloatEditor::StartingKey(wxKeyEvent& event) +{ + long keycode = event.KeyCode(); + if ( isdigit(keycode) || + keycode == '+' || keycode == '-' || keycode == '.' ) + { + wxGridCellTextEditor::StartingKey(event); + + // skip Skip() below + return; + } + + event.Skip(); +} + // ---------------------------------------------------------------------------- // wxGridCellBoolEditor // ---------------------------------------------------------------------------- @@ -738,20 +930,19 @@ void wxGridCellRenderer::Draw(wxGrid& grid, dc.DrawRectangle(rect); } +wxGridCellRenderer::~wxGridCellRenderer() +{ +} + // ---------------------------------------------------------------------------- // wxGridCellStringRenderer // ---------------------------------------------------------------------------- -void wxGridCellStringRenderer::Draw(wxGrid& grid, - wxGridCellAttr& attr, - wxDC& dc, - const wxRect& rectCell, - int row, int col, - bool isSelected) +void wxGridCellStringRenderer::SetTextColoursAndFont(wxGrid& grid, + wxGridCellAttr& attr, + wxDC& dc, + bool isSelected) { - wxGridCellRenderer::Draw(grid, attr, dc, rectCell, row, col, isSelected); - - // now we only have to draw the text dc.SetBackgroundMode( wxTRANSPARENT ); // TODO some special colours for attr.IsReadOnly() case? @@ -766,21 +957,107 @@ void wxGridCellStringRenderer::Draw(wxGrid& grid, dc.SetTextBackground( attr.GetBackgroundColour() ); dc.SetTextForeground( attr.GetTextColour() ); } + dc.SetFont( attr.GetFont() ); +} + +void wxGridCellStringRenderer::Draw(wxGrid& grid, + wxGridCellAttr& attr, + wxDC& dc, + const wxRect& rectCell, + int row, int col, + bool isSelected) +{ + wxGridCellRenderer::Draw(grid, attr, dc, rectCell, row, col, isSelected); + + // now we only have to draw the text + SetTextColoursAndFont(grid, attr, dc, isSelected); int hAlign, vAlign; attr.GetAlignment(&hAlign, &vAlign); wxRect rect = rectCell; - rect.x++; - rect.y++; - rect.width -= 2; - rect.height -= 2; + rect.Inflate(-1); grid.DrawTextRectangle(dc, grid.GetCellValue(row, col), rect, hAlign, vAlign); } +void wxGridCellNumberRenderer::Draw(wxGrid& grid, + wxGridCellAttr& attr, + wxDC& dc, + const wxRect& rectCell, + int row, int col, + bool isSelected) +{ + wxGridCellRenderer::Draw(grid, attr, dc, rectCell, row, col, isSelected); + + SetTextColoursAndFont(grid, attr, dc, isSelected); + + // draw the text right aligned by default + int hAlign, vAlign; + attr.GetAlignment(&hAlign, &vAlign); + hAlign = wxRIGHT; + + wxRect rect = rectCell; + rect.Inflate(-1); + + wxGridTableBase *table = grid.GetTable(); + wxString text; + if ( table->CanGetValueAs(row, col, wxGRID_VALUE_NUMBER) ) + { + text.Printf(_T("%ld"), table->GetValueAsLong(row, col)); + } + //else: leave the string empty or put 0 into it? + + grid.DrawTextRectangle(dc, text, rect, hAlign, vAlign); +} + +// ---------------------------------------------------------------------------- +// wxGridCellFloatRenderer +// ---------------------------------------------------------------------------- + +wxGridCellFloatRenderer::wxGridCellFloatRenderer(int width, int precision) +{ + SetWidth(width); + SetPrecision(precision); +} + +void wxGridCellFloatRenderer::Draw(wxGrid& grid, + wxGridCellAttr& attr, + wxDC& dc, + const wxRect& rectCell, + int row, int col, + bool isSelected) +{ + wxGridCellRenderer::Draw(grid, attr, dc, rectCell, row, col, isSelected); + + SetTextColoursAndFont(grid, attr, dc, isSelected); + + // draw the text right aligned by default + int hAlign, vAlign; + attr.GetAlignment(&hAlign, &vAlign); + hAlign = wxRIGHT; + + wxRect rect = rectCell; + rect.Inflate(-1); + + wxGridTableBase *table = grid.GetTable(); + wxString text; + if ( table->CanGetValueAs(row, col, wxGRID_VALUE_FLOAT) ) + { + if ( !m_format ) + { + m_format.Printf(_T("%%%d.%d%%f"), m_width, m_precision); + } + + text.Printf(m_format, table->GetValueAsDouble(row, col)); + } + //else: leave the string empty or put 0 into it? + + grid.DrawTextRectangle(dc, text, rect, hAlign, vAlign); +} + // ---------------------------------------------------------------------------- // wxGridCellBoolRenderer // ---------------------------------------------------------------------------- @@ -1475,13 +1752,13 @@ wxString wxGridTableBase::GetColLabelValue( int col ) wxString wxGridTableBase::GetTypeName( int WXUNUSED(row), int WXUNUSED(col) ) { - return wxT("string"); + return wxGRID_VALUE_STRING; } bool wxGridTableBase::CanGetValueAs( int WXUNUSED(row), int WXUNUSED(col), const wxString& typeName ) { - return typeName == wxT("string"); + return typeName == wxGRID_VALUE_STRING; } bool wxGridTableBase::CanSetValueAs( int row, int col, const wxString& typeName ) @@ -2288,13 +2565,18 @@ void wxGrid::Create() m_rowLabelWidth = WXGRID_DEFAULT_ROW_LABEL_WIDTH; m_colLabelHeight = WXGRID_DEFAULT_COL_LABEL_HEIGHT; - // data type registration + // data type registration: register all standard data types + // TODO: may be allow the app to selectively disable some of them? m_typeRegistry = new wxGridTypeRegistry; - RegisterDataType(wxT("string"), new wxGridCellStringRenderer, - new wxGridCellTextEditor); - RegisterDataType(wxT("bool"), new wxGridCellBoolRenderer, - new wxGridCellBoolEditor); - + RegisterDataType(wxGRID_VALUE_STRING, + new wxGridCellStringRenderer, + new wxGridCellTextEditor); + RegisterDataType(wxGRID_VALUE_BOOL, + new wxGridCellBoolRenderer, + new wxGridCellBoolEditor); + RegisterDataType(wxGRID_VALUE_NUMBER, + new wxGridCellNumberRenderer, + new wxGridCellNumberEditor); // subwindow components that make up the wxGrid m_cornerLabelWin = new wxGridCornerLabelWindow( this, -- 2.47.2